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


177

У мене панди DataFrame заповнені здебільшого реальними цифрами, але в цьому є і кілька nanзначень.

Як я можу замінити nans на середні стовпці, де вони є?

Це питання дуже схоже на це: numpy масив: замініть значення nan середніми стовпцями, але, на жаль, наведене там рішення не працює для панд 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
ПОПЕРЕДЖЕННЯ: якщо ви хочете використовувати це для машинного навчання / наукових даних: з точки зору науки про дані неправильно спочатку замінити NA, а потім розділити на поїзд і випробувати ... Ви СПРИКУЙТЕ спочатку розділити на поїзд і випробувати, а потім замінити NA на маю на увазі поїзд, а потім застосуйте цю тему, що склалася для попередньої обробки, для тестування, дивіться відповідь, що стосується sklearn нижче!
Фабіан Вернер

2
@ amalik2205, оскільки в іншому випадку ви просочуєте інформацію з тестового набору в навчальний набір! Уявіть це так: у нас є 100 рядків даних і ми вважаємо стовпчик x. Перші 99 записів x - це NA. Ми хочемо розділити рядок 100 як тестовий набір. Припустимо, що рядок 100 має значення 20 у стовпці х. Тоді ви заміните всі записи в навчальному наборі в колонці 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 ()) не працював, застосовується лише ваша версія з. 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
Надайте трохи пояснень, як це вирішує проблему.
Gurwinder Singh

10

Безпосередньо використовуйте df.fillna(df.mean())для заповнення всіх нульових значень середнім значенням

Якщо ви хочете заповнити нульове значення середнім значенням цього стовпця, ви можете використовувати це

припустимо, x=df['Item_Weight']тут Item_Weightназва стовпця

тут ми призначаємо (заповніть нульові значення x середнім значенням x у x)

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.