Python - использование SkLearn Imputer
У меня есть следующий вопрос: у меня есть пандас dataframe, в котором пропущенные значения отмечены строкой na
, Я хочу запустить Imputer на нем, чтобы заменить отсутствующие значения на среднее значение в столбце. Согласно документации sklearn, параметр missing_values
должен помочь мне с этим:
missing_values: целое число или "NaN", необязательный (по умолчанию = "NaN") Заполнитель для пропущенных значений. Все вхождения пропущенных_значений будут вменяться. Для пропущенных значений, закодированных как np.nan, используйте строковое значение "NaN".
В моем понимании это означает, что если я напишу
df = pd.read_csv(filename)
imp = Imputer(missing_values='na')
imp.fit_transform(df)
это означало бы, что импуттер заменяет что-либо в кадре данных на na
значение со средним значением столбца. Однако вместо этого я получаю ошибку:
ValueError: could not convert string to float: na
Что я неправильно понимаю? Не так ли должен работать импутер? Как я могу заменить na
строки со средним значением, тогда? Должен ли я просто использовать лямбду для этого?
Спасибо!
3 ответа
Так как вы говорите, что хотите заменить эти 'na'
по среднему значению столбца, я предполагаю, что не пропущенные значения действительно являются числами с плавающей точкой. Проблема в том, что панды не распознают строку 'na'
как отсутствующее значение, и поэтому читает столбец с dtype object
вместо какого-то аромата float
,
В данном случае рассмотрим следующее .csv
файл:
test.csv
col1,col2
1.0,1.0
2.0,2.0
3.0,3.0
na,4.0
5.0,5.0
С наивным импортом df = pd.read_csv('test.csv')
, df.dtypes
говорит нам, что col1
имеет тип object
а также col2
имеет тип float64
, Но как вы понимаете, что такое куча объектов?
Решение состоит в том, чтобы сказать pd.read_csv()
интерпретировать строку 'na'
как отсутствующее значение:
df = pd.read_csv('test.csv', na_values='na')
Результирующий кадр данных имеет оба столбца типа dtype. float64
и теперь вы можете использовать свой импутер.
Здесь нужно обратить внимание на несколько вещей.
Убедитесь, что вы не вменяете переменные типа "объект" или категориальные переменные, вы можете посмотреть на свои данные следующим образом:
df = pd.read_csv(filename)
print(df.info(null_counts=True))
Последний столбец должен быть типа
Давайте посмотрим на пример:
df = pd.DataFrame({'A' : [1, 2, 2, 2, 'NaN', 3, 4, 5, 6], 'B' : [3, 3, 'NaN', 3, 3, 4, 3, 3, 3]})
выход:
df.head()
A B
---------
0 1 3
1 2 3
2 2 NaN
3 2 3
4 NaN 3
Теперь давайте посмотрим на типы
df.info(null_counts=True)
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 9 entries, 0 to 8
Data columns (total 2 columns):
0 9 non-null float64
1 9 non-null float64
dtypes: float64(2)
memory usage: 224.0 bytes
Сейчас вменяется:
from sklearn.preprocessing import Imputer
imputer = Imputer(missing_values='NaN', strategy='most_frequent', axis=0)
df_imputed = pd.DataFrame(imputer.fit_transform(df))
df_imputed.head()
0 1
-----------
0 1.0 3.0
1 2.0 3.0
2 2.0 3.0
3 2.0 3.0
4 2.0 3.0
Теперь это все хорошо и хорошо, но нельзя сделать по категориям (тип Object / String)
Одним из способов справиться с этим является изменение категорийных функций на числовые, что-то вроде этого:
df_with_cat = pd.DataFrame({'A': ['ios', 'android', 'web', 'NaN'], 'B' : [4, 4, 'NaN', 2]})
df_with_cat.head()
A B
-------------
0 ios 4
1 android 4
2 web NaN
3 NaN 2
И информация
df_with_cat.info(null_counts=True)
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 2 columns):
A 4 non-null object
B 4 non-null object
dtypes: object(2)
memory usage: 144.0+ bytes
Мы точно знаем, что B является числовым, поэтому давайте сделаем это:
df_with_cat['B'] = df_with_cat['B'].astype(np.float)
df_with_cat.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 2 columns):
A 4 non-null object
B 3 non-null float64
dtypes: float64(1), object(1)
memory usage: 144.0+ bytes
Если бы мы использовали тот же самый импутер сверху, мы получили бы ошибку (вы можете попробовать это)
Теперь давайте преобразуем категории "А" в числа:
CATEGORICAL_FEATURES = [
'A',
]
data_dum = pd.get_dummies(df_with_cat, columns=['A'], drop_first=True)
data_dum.head()
B A_android A_ios A_web
---------------------------------
0 4 0 1 0
1 4 1 0 0
2 NaN 0 0 1
3 2 0 0 0
Теперь мы можем запустить тот же самый Imputer сверху на нашем фрейме данных.
Вот ошибка, которую я получал
IndexError: в будущем 0-й логический массив будет интерпретироваться как действительный логический индекс
В моем случае у меня была проблема со "медианной" стратегией, изменив ее на среднее или Most_frequent сработало.
Первый импорт pandas
затем прочитайте your_file_name.csv
, А также iloc
определяется pandas.DataFrame.iloc и является целочисленной индексацией Пурли для местоположения по позиции. Здесь формат iloc[for row index , for column index]
где a, b, c, d - целые числа ab, c, d также могут быть пустыми
import pandas as pd
dataSet = pd.read_csv('your_file_name.csv')
X = dataSet.iloc[ a:b , c:d].values
если вы используете без.values, вы не сможете использовать его в imputer для преобразования
здесь после импорта Imputer
определить ваш Imputer
параметры missing_values
знак равно
"пропущенные значения в данных, которые вы хотите заменить",strategy ="mean"
(Есть еще две стратегии, которые следуют, то есть медиана и чаще всего встречаются в вашем наборе данных, но по умолчанию это среднее. Затем установите axis = (0 для столбца и 1 для строки), другие являются копиями и подробностями), вы можете прочитать больше об этом на
from sklearn.preprocessing import Imputer
i = Imputer(missing_values="NaN", strategy="mean", axis=0)
вписать данные в ваш определенный способ Imputer, а затем преобразовать его с помощью метода преобразования. это вернет массив типа данных = объект
i = i.fit(X[a:b, c:d])
X[a:b, c:d ] = i.transform(X[a:b,c:d])
Помните, что выбранные вами столбцы содержат только значения типа float или integer, в противном случае это может показать, что ошибка не может преобразовать строку в float