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.