Обманывать категорически отсутствующие ценности в scikit-learn

У меня есть данные pandas с некоторыми столбцами типа текста. Есть несколько значений NaN вместе с этими текстовыми столбцами. То, что я пытаюсь сделать, – это навязать эти NaN с помощью sklearn.preprocessing. Imputer (заменив NaN на наиболее частое значение). Проблема в реализации. Предположим, что имеется информационная рамка Pandas df с 30 столбцами, 10 из которых имеют категориальный характер. После запуска

from sklearn.preprocessing import Imputer imp = Imputer(missing_values='NaN', strategy='most_frequent', axis=0) imp.fit(df) 

Python генерирует ошибку: «не удалось преобразовать строку в float:« run1 », где« run1 »является обычным (не пропускаемым) значением из первого столбца с категориальными данными.

Любая помощь будет очень желанной

4 Solutions collect form web for “Обманывать категорически отсутствующие ценности в scikit-learn”

Чтобы использовать средние значения для числовых столбцов и наиболее частое значение для нечисловых столбцов, вы можете сделать что-то вроде этого. Вы можете различать целые числа и поплавки. Возможно, имеет смысл использовать медиану для целых столбцов.

 import pandas as pd import numpy as np from sklearn.base import TransformerMixin class DataFrameImputer(TransformerMixin): def __init__(self): """Impute missing values. Columns of dtype object are imputed with the most frequent value in column. Columns of other types are imputed with mean of column. """ def fit(self, X, y=None): self.fill = pd.Series([X[c].value_counts().index[0] if X[c].dtype == np.dtype('O') else X[c].mean() for c in X], index=X.columns) return self def transform(self, X, y=None): return X.fillna(self.fill) data = [ ['a', 1, 2], ['b', 1, 1], ['b', 2, 2], [np.nan, np.nan, np.nan] ] X = pd.DataFrame(data) xt = DataFrameImputer().fit_transform(X) print('before...') print(X) print('after...') print(xt) того, как import pandas as pd import numpy as np from sklearn.base import TransformerMixin class DataFrameImputer(TransformerMixin): def __init__(self): """Impute missing values. Columns of dtype object are imputed with the most frequent value in column. Columns of other types are imputed with mean of column. """ def fit(self, X, y=None): self.fill = pd.Series([X[c].value_counts().index[0] if X[c].dtype == np.dtype('O') else X[c].mean() for c in X], index=X.columns) return self def transform(self, X, y=None): return X.fillna(self.fill) data = [ ['a', 1, 2], ['b', 1, 1], ['b', 2, 2], [np.nan, np.nan, np.nan] ] X = pd.DataFrame(data) xt = DataFrameImputer().fit_transform(X) print('before...') print(X) print('after...') print(xt) 

который печатает,

 before... 0 1 2 0 a 1 2 1 b 1 1 2 b 2 2 3 NaN NaN NaN after... 0 1 2 0 a 1.000000 2.000000 1 b 1.000000 1.000000 2 b 2.000000 2.000000 3 b 1.333333 1.666667 

Этот код заполняет серию с наиболее частой категорией:

 import pandas as pd import numpy as np # create fake data m = pd.Series(list('abca')) m.iloc[1] = np.nan #artificially introduce nan print('m = ') print(m) #make dummy variables, count and sort descending: most_common = pd.get_dummies(m).sum().sort_values(ascending=False).index[0] def replace_most_common(x): if pd.isnull(x): return most_common else: return x new_m = m.map(replace_most_common) #apply function to original data print('new_m = ') print(new_m) 

Выходы:

 m = 0 a 1 NaN 2 c 3 a dtype: object new_m = 0 a 1 a 2 c 3 a dtype: object 

Копируя и изменяя ответ sveitser, я сделал imputer для объекта pandas.Series

 import numpy import pandas from sklearn.base import TransformerMixin class SeriesImputer(TransformerMixin): def __init__(self): """Impute missing values. If the Series is of dtype Object, then impute with the most frequent object. If the Series is not of dtype Object, then impute with the mean. """ def fit(self, X, y=None): if X.dtype == numpy.dtype('O'): self.fill = X.value_counts().index[0] else : self.fill = X.mean() return self def transform(self, X, y=None): return X.fillna(self.fill) 

Чтобы использовать его, вы должны:

 # Make a series s1 = pandas.Series(['k', 'i', 't', 't', 'e', numpy.NaN]) a = SeriesImputer() # Initialize the imputer a.fit(s1) # Fit the imputer s2 = a.transform(s1) # Get a new series 

Аналогичный. Изменить Imputer для strategy='most_frequent' :

 class GeneralImputer(Imputer): def __init__(self, **kwargs): Imputer.__init__(self, **kwargs) def fit(self, X, y=None): if self.strategy == 'most_frequent': self.fills = pd.DataFrame(X).mode(axis=0).squeeze() self.statistics_ = self.fills.values return self else: return Imputer.fit(self, X, y=y) def transform(self, X): if hasattr(self, 'fills'): return pd.DataFrame(X).fillna(self.fills).values.astype(str) else: return Imputer.transform(self, X) 

где pandas.DataFrame.mode() находит наиболее частое значение для каждого столбца, а затем pandas.DataFrame.fillna() заполняет эти значения отсутствующими значениями. Другие значения strategy по-прежнему обрабатываются одинаково с помощью Imputer .

Python - лучший язык программирования в мире.