Преобразование str в int с пустыми ячейками pandas
import pandas as pd
df = pd.DataFrame({'Минимум': [0, 0, 0, 0, 0, 0, 0],
'vendor1': ['', '', '65000', '', '14000', '11000', ''],
'vendor2': ['22000', '12000', '', '', '15000', '', '71000'],
'vendor3': ['', '', '', '', '', '9900', ''],
'vendor4': ['23000', '', '', '', '13600', '', '76000']})
Имеется DataFrame df, который имеет типы:
Задача состоит в том, что бы в каждой строке от vendor1 до vendor4 включительно найти минимальное значение и вставить его в первый столбец 'Минимум'. Что бы в итоге первый столбец состоял из значений: 22000, 12000, 65000, 0, 13600, 9900, 71000. И сюда логично напрашивается код:
df['Минимум'] = df.loc[:,'vendor1':'vendor4'].min(axis=1)
Но я не могу совладать с типами столбцов и ячеек, т.к. знаний не хватает. Понимаю, что сейчас строки в df не могут иметь параметра минимум и поэтому код не работает, но если все переделать в int то программа ругается на пустые ячейки. Если начать использовать fillna(0).dtype(int) то код фактически работает, но нули мешают. В общем я устал и запутался.
Вопрос.
Подскажите, как в нужных в столбцах (от vendor1 до vendor4) преобразовать типы данных (в int) только заполненных ячеек, и при этом игнорировать пустые ячейки? Ну и в дальнейшем что бы минимальное значение выбиралось из нужного диапазона только в том случае, если ячейка заполнена цифрой.
Иными словами нужно, что бы получилось так:
Спасибо.
Ответы (2 шт):
Для преобразования '' в NaN используем способ mask(df == ''), другие способы есть тут.
Для преобразования строковых значений в числа используется pandas.Int64Dtype.
Второй строкой, меняем NaN на 0 и конвертируем в целое.
df['Минимум'] = df.loc[:, 'vendor1':'vendor4'].mask(df == '').astype(pd.Int64Dtype()).min(axis=1)
df['Минимум'] = df['Минимум'].fillna(0).astype(int)
df
Out[6]:
Минимум vendor1 vendor2 vendor3 vendor4
0 22000 22000 23000
1 12000 12000
2 65000 65000
3 0
4 13600 14000 15000 13600
5 9900 11000 9900
6 71000 71000 76000
Можно привести в числовому типу с коррекцией ошибок:
df["Минимум"] = df.loc[:,'vendor1':'vendor4'].apply(pd.to_numeric, errors='coerce').astype('Int64').min(axis=1).fillna(0)
Минимум vendor1 vendor2 vendor3 vendor4
0 22000.0 22000 23000
1 12000.0 12000
2 65000.0 65000
3 0.0
4 13600.0 14000 15000 13600
5 9900.0 11000 9900
6 71000.0 71000 76000
Либо, as per @CrazyElf, можно явно сохранить тип int:
df["Минимум"] = df.loc[:,'vendor1':'vendor4'].apply(pd.to_numeric, errors='coerce').astype('Int64').min(axis=1, numeric_only=True).fillna(0)
Минимум vendor1 vendor2 vendor3 vendor4
0 22000 22000 23000
1 12000 12000
2 65000 65000
3 0
4 13600 14000 15000 13600
5 9900 11000 9900
6 71000 71000 76000
```

