Заполнение пропущенных данных для модели машинного обучения
Нужно заполнить пропущенные значения для модели машинного обучения. С помощью функции calculate_means. (Она заранее написана в задании)
def calculate_means(numeric_data):
means = np.zeros(numeric_data.shape[1])
for j in range(numeric_data.shape[1]):
to_sum = numeric_data.iloc[:,j]
indices = np.nonzero(~numeric_data.iloc[:,j].isnull())[0]
correction = np.amax(to_sum[indices])
to_sum /= correction
for i in indices:
means[j] += to_sum[i]
means[j] /= indices.size
means[j] *= correction
return pd.Series(means, numeric_data.columns)
data = pd.read_csv('data.csv')
X = data.drop('Grant.Status', 1)
y = data['Grant.Status']
numeric_cols = ['RFCD.Percentage.1', 'RFCD.Percentage.2', 'RFCD.Percentage.3',
'RFCD.Percentage.4', 'RFCD.Percentage.5',
'SEO.Percentage.1', 'SEO.Percentage.2', 'SEO.Percentage.3',
'SEO.Percentage.4', 'SEO.Percentage.5',
'Year.of.Birth.1', 'Number.of.Successful.Grant.1', 'Number.of.Unsuccessful.Grant.1']
categorical_cols = list(set(X.columns.values.tolist()) - set(numeric_cols))
means = calculate_means(X[numeric_cols])
X_real_mean = X[numeric_cols]
for i in range(len(numeric_cols)):
X_real_mean.iloc[:, i] = X_real_mean.iloc[:, i].fillna(means.values[i])
Но не могу понять, что делать с этой ошибкой:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-17-7d79cc69311f> in <module>
2 X_real_zeros = X[numeric_cols].fillna(0)
3
----> 4 means = calculate_means(X[numeric_cols])
5 X_real_mean = X[numeric_cols]
6 for i in range(len(numeric_cols)):
<ipython-input-8-a1d3e6085deb> in calculate_means(numeric_data)
3 for j in range(numeric_data.shape[1]):
4 to_sum = numeric_data.iloc[:,j]
----> 5 indices = np.nonzero(~numeric_data.iloc[:,j].isnull())[0]
6 correction = np.amax(to_sum[indices])
7 to_sum /= correction
<__array_function__ internals> in nonzero(*args, **kwargs)
~\anaconda3\lib\site-packages\numpy\core\fromnumeric.py in nonzero(a)
1906
1907 """
-> 1908 return _wrapfunc(a, 'nonzero')
1909
1910
~\anaconda3\lib\site-packages\numpy\core\fromnumeric.py in _wrapfunc(obj, method, *args, **kwds)
53 bound = getattr(obj, method, None)
54 if bound is None:
---> 55 return _wrapit(obj, method, *args, **kwds)
56
57 try:
~\anaconda3\lib\site-packages\numpy\core\fromnumeric.py in _wrapit(obj, method, *args, **kwds)
46 if not isinstance(result, mu.ndarray):
47 result = asarray(result)
---> 48 result = wrap(result)
49 return result
50
~\anaconda3\lib\site-packages\pandas\core\generic.py in __array_wrap__(self, result, context)
1788 return result
1789 d = self._construct_axes_dict(self._AXIS_ORDERS, copy=False)
-> 1790 return self._constructor(result, **d).__finalize__(
1791 self, method="__array_wrap__"
1792 )
~\anaconda3\lib\site-packages\pandas\core\series.py in __init__(self, data, index, dtype, name,
copy, fastpath)
311 try:
312 if len(index) != len(data):
--> 313 raise ValueError(
314 f"Length of passed values is {len(data)}, "
315 f"index implies {len(index)}."
ValueError: Length of passed values is 1, index implies 6000.
Ответы (2 шт):
Если добавить в той строке на которую ругается .values, то перестаёт ругаться и вроде работает:
indices = np.nonzero(~numeric_data.iloc[:,j].isnull().values)[0]
^^^^^^^
Природу сего явления объяснить не могу, видимо, какое-то недопонимание между данными Pandas.Series и функцией Numpy.
Вместо монстрообразной и медленной (невекторизированной) функции calculate_means(), которая к тому же молча изменяет данные в переданном ей фрейме, можно воспользоваться простым векторизированным решением:
In [148]: df = pd.DataFrame({"a":[1, 2 ,np.nan], "b":[1,2,3]})
In [149]: df
Out[149]:
a b
0 1.0 1
1 2.0 2
2 NaN 3
In [150]: means = df.apply(lambda col: col.dropna().mean())
In [151]: means
Out[151]:
a 1.5
b 2.0
dtype: float64
Демонстрация того, как исправленная функция calculate_means() меняет значения переданного ей фрейма:
In [152]: df
Out[152]:
a b
0 1.0 1
1 2.0 2
2 NaN 3
In [153]: calculate_means(df)
Out[153]:
a 1.5
b 2.0
dtype: float64
In [154]: df
Out[154]:
a b
0 0.5 1
1 1.0 2
2 NaN 3
обратите внимание на изменившиеся значения в столбце a!