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.