pandas DataFrame: заменить значения nan на среднее значение столбцов


177

У меня есть пандас DataFrame, заполненный в основном реальными числами, но в нем также есть несколько nanзначений.

Как я могу заменить nanсредние значения столбцов, где они находятся?

Этот вопрос очень похож на этот: массив numpy: замените значения nan на среднее значение столбцов, но, к сожалению, приведенное там решение не работает для pandas DataFrame.

Ответы:


273

Вы можете просто использовать DataFrame.fillnaдля nanнепосредственного заполнения :

In [27]: df 
Out[27]: 
          A         B         C
0 -0.166919  0.979728 -0.632955
1 -0.297953 -0.912674 -1.365463
2 -0.120211 -0.540679 -0.680481
3       NaN -2.027325  1.533582
4       NaN       NaN  0.461821
5 -0.788073       NaN       NaN
6 -0.916080 -0.612343       NaN
7 -0.887858  1.033826       NaN
8  1.948430  1.025011 -2.982224
9  0.019698 -0.795876 -0.046431

In [28]: df.mean()
Out[28]: 
A   -0.151121
B   -0.231291
C   -0.530307
dtype: float64

In [29]: df.fillna(df.mean())
Out[29]: 
          A         B         C
0 -0.166919  0.979728 -0.632955
1 -0.297953 -0.912674 -1.365463
2 -0.120211 -0.540679 -0.680481
3 -0.151121 -2.027325  1.533582
4 -0.151121 -0.231291  0.461821
5 -0.788073 -0.231291 -0.530307
6 -0.916080 -0.612343 -0.530307
7 -0.887858  1.033826 -0.530307
8  1.948430  1.025011 -2.982224
9  0.019698 -0.795876 -0.046431

Строка документа fillnaговорит, что это valueдолжен быть скаляр или диктат, однако, похоже, он работает и с Series. Если вы хотите передать диктовку, вы можете использовать df.mean().to_dict().


10
df.fillna(df.mean())вернет новый фрейм данных, поэтому вам придется написать, df=df.fillna(df.mean())чтобы сохранить его.
Яннис

Любые идеи, почему я могу получить неправильную сумму вменяется для среднего с помощью этого?
bernando_vialli

25
Вместо df=df.fillna(df.mean())тебя тоже можно было бы использоватьdf.fillna(df.mean(), inplace=True)
Андерсон Пиментел

20
ВНИМАНИЕ: если вы хотите использовать это для машинного обучения / Data Science: с точки зрения Data Science неправильно сначала заменять NA, а затем разбивать на обучающие и тестируемые ... Сначала вы ДОЛЖНЫ делиться на обучающие и тестируемые, а затем заменять NA на Имеется в виду на поезде, а затем применить эту модель с предварительной обработкой состояния для тестирования, см. ответ с участием sklearn ниже!
Фабиан Вернер

2
@ amalik2205, потому что иначе вы пропускаете информацию из тестового набора в тренировочный набор! Представьте себе это так: у нас есть 100 строк данных, и мы рассматриваем столбец х. Первые 99 записей х являются NA. Мы хотим отделить строку 100 в качестве тестового набора. Давайте предположим, что строка 100 имеет значение 20 в столбце x. Затем вы замените все записи в обучающем наборе в столбце x на 20, значение, полученное на 100% из испытательного набора. Следовательно, оценка может обмануть вас!
Фабиан Вернер


28
In [16]: df = DataFrame(np.random.randn(10,3))

In [17]: df.iloc[3:5,0] = np.nan

In [18]: df.iloc[4:6,1] = np.nan

In [19]: df.iloc[5:8,2] = np.nan

In [20]: df
Out[20]: 
          0         1         2
0  1.148272  0.227366 -2.368136
1 -0.820823  1.071471 -0.784713
2  0.157913  0.602857  0.665034
3       NaN -0.985188 -0.324136
4       NaN       NaN  0.238512
5  0.769657       NaN       NaN
6  0.141951  0.326064       NaN
7 -1.694475 -0.523440       NaN
8  0.352556 -0.551487 -1.639298
9 -2.067324 -0.492617 -1.675794

In [22]: df.mean()
Out[22]: 
0   -0.251534
1   -0.040622
2   -0.841219
dtype: float64

Примените к каждому столбцу среднее значение этих столбцов и заполните

In [23]: df.apply(lambda x: x.fillna(x.mean()),axis=0)
Out[23]: 
          0         1         2
0  1.148272  0.227366 -2.368136
1 -0.820823  1.071471 -0.784713
2  0.157913  0.602857  0.665034
3 -0.251534 -0.985188 -0.324136
4 -0.251534 -0.040622  0.238512
5  0.769657 -0.040622 -0.841219
6  0.141951  0.326064 -0.841219
7 -1.694475 -0.523440 -0.841219
8  0.352556 -0.551487 -1.639298
9 -2.067324 -0.492617 -1.675794

5
Я не знаю почему, но df.fillna (df.mean ()) не работал, только ваша версия с apply. Python 3
Rocketq

12
# To read data from csv file
Dataset = pd.read_csv('Data.csv')

X = Dataset.iloc[:, :-1].values

# To calculate mean use imputer class
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(missing_values=np.nan, strategy='mean')
imputer = imputer.fit(X[:, 1:3])
X[:, 1:3] = imputer.transform(X[:, 1:3])

В чем преимущество всего этого перед гораздо более простыми альтернативами?
AMC

@Roshan Jha Всегда лучше объяснить логику. Есть много способов сделать ту же задачу в R & Python. Однако, если вы предлагаете что-то другое, вы можете указать на некоторые преимущества этого
д-р Ниша Арора

10

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

sub2['income'] = sub2['income'].fillna((sub2['income'].mean()))

3
Пожалуйста, предоставьте некоторые объяснения того, как это решает проблему.
Гурвиндер Сингх

10

Непосредственно используйте, df.fillna(df.mean())чтобы заполнить все нулевое значение средним

Если вы хотите заполнить нулевое значение средним значением этого столбца, вы можете использовать это

Предположим, x=df['Item_Weight']здесь Item_Weightесть имя столбца

здесь мы присваиваем (заполняем нулевые значения х средним значением х в х)

df['Item_Weight'] = df['Item_Weight'].fillna((df['Item_Weight'].mean()))

Если вы хотите заполнить нулевое значение какой-либо строкой, используйте

вот Outlet_sizeназвание столбца

df.Outlet_Size = df.Outlet_Size.fillna('Missing')

9

Другой вариант, кроме перечисленных выше:

df = df.groupby(df.columns, axis = 1).transform(lambda x: x.fillna(x.mean()))

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


7

Панды: Как заменить значения NaN ( nan) на среднюю (среднюю), медиану или другую статистику одного столбца

Скажите, что ваш DataFrame - dfи у вас есть один столбец nr_items. Это: df['nr_items']

Если вы хотите , чтобы заменить те NaNзначения вашей колонки df['nr_items']с средней частью колонны :

Используйте метод .fillna():

mean_value=df['nr_items'].mean()
df['nr_item_ave']=df['nr_items'].fillna(mean_value)

Я создал новый dfстолбец с именем nr_item_aveдля хранения нового столбца со NaNзначениями, замененными meanзначением столбца.

Вы должны быть осторожны при использовании mean. Если у вас есть выбросы, рекомендуется использоватьmedian


0

использование класса предварительной обработки библиотеки sklearn

from sklearn.impute import SimpleImputer
missingvalues = SimpleImputer(missing_values = np.nan, strategy = 'mean', axis = 0)
missingvalues = missingvalues.fit(x[:,1:3])
x[:,1:3] = missingvalues.transform(x[:,1:3])

Примечание. В последней версии missing_valuesзначение параметра изменяется np.nanсNaN

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.