panda DataFrame: ganti nilai nan dengan rata-rata kolom

177

Saya punya panda DataFrame yang sebagian besar diisi dengan bilangan real, tetapi ada beberapa nannilai di dalamnya juga.

Bagaimana saya bisa mengganti nans dengan rata-rata kolom di mana mereka?

Pertanyaan ini sangat mirip dengan yang satu ini: numpy array: ganti nilai-nilai nan dengan rata-rata kolom tetapi, sayangnya, solusi yang diberikan di sana tidak berfungsi untuk panda DataFrame.

piokuc
sumber

Jawaban:

273

Anda cukup menggunakan DataFrame.fillnauntuk mengisi nanlangsung:

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

Doktring fillnamengatakan bahwa itu valueharus skalar atau dikt, bagaimanapun, tampaknya bekerja dengan Seriesbaik juga. Jika Anda ingin mengirimkan dikt, Anda dapat menggunakannya df.mean().to_dict().

bmu
sumber
10
df.fillna(df.mean())akan mengembalikan bingkai data baru, jadi Anda harus menulis df=df.fillna(df.mean())untuk menyimpannya.
yannis
ada ide mengapa saya mungkin mendapatkan jumlah yang salah diperhitungkan untuk mean menggunakan ini?
bernando_vialli
25
Alih-alih df=df.fillna(df.mean())Anda juga bisa menggunakandf.fillna(df.mean(), inplace=True)
Anderson Pimentel
20
PERHATIAN: jika Anda ingin menggunakan ini untuk Pembelajaran Mesin / Ilmu Data: dari perspektif Ilmu Data salah untuk pertama-tama mengganti NA dan kemudian membaginya menjadi kereta dan menguji ... Anda HARUS membaginya menjadi kereta dan tes, kemudian ganti NA dengan maksud di kereta dan kemudian menerapkan model preprocessing stateful ini untuk menguji, lihat jawaban yang melibatkan sklearn di bawah!
Fabian Werner
2
@ amalik2205 karena jika tidak, Anda membocorkan informasi dari set tes ke set pelatihan! Bayangkan seperti ini: Kami memiliki 100 baris data dan kami menganggap kolom x. 99 entri pertama x adalah NA. Kami ingin memisahkan baris 100 sebagai set uji. Misalkan baris 100 memiliki nilai 20 di kolom x. Kemudian Anda akan mengganti semua entri dalam set pelatihan di kolom x dengan 20, nilai yang datang 100% dari set tes. Karenanya, evaluasi mungkin menipu Anda!
Fabian Werner
51

Mencoba:

sub2['income'].fillna((sub2['income'].mean()), inplace=True)
Ammar Shigri
sumber
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

Terapkan per kolom rata-rata kolom itu dan isi

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
Jeff
sumber
5
Saya tidak tahu mengapa, tetapi df.fillna (df.mean ()) tidak berfungsi, hanya versi Anda yang berlaku. 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])
Roshan jha
sumber
Apa keuntungan dari semua ini dibanding alternatif yang jauh lebih sederhana?
AMC
@Roshan Jha Itu selalu lebih baik untuk menjelaskan logika. Ada banyak cara untuk melakukan tugas yang sama di R & Python. Namun, jika Anda menyarankan sesuatu yang berbeda, Anda mungkin ingin menunjukkan beberapa keuntungan untuk melakukannya
Dr Nisha Arora
10

Jika Anda ingin menyalahkan nilai yang hilang dengan mean dan Anda ingin pergi kolom demi kolom, maka ini hanya akan menyalahkan dengan rata-rata kolom itu. Ini mungkin sedikit lebih mudah dibaca.

sub2['income'] = sub2['income'].fillna((sub2['income'].mean()))
Pranay Aryal
sumber
3
Harap berikan beberapa penjelasan tentang bagaimana ini memecahkan masalah.
Gurwinder Singh
10

Langsung digunakan df.fillna(df.mean())untuk mengisi semua nilai nol dengan mean

Jika Anda ingin mengisi nilai nol dengan rata-rata kolom itu maka Anda dapat menggunakan ini

anggap di x=df['Item_Weight']sini Item_Weightadalah nama kolom

di sini kita menugaskan (mengisi nilai nol dari x dengan rata-rata x ke x)

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

Jika Anda ingin mengisi nilai nol dengan beberapa string kemudian gunakan

di sini Outlet_sizeadalah nama kolom

df.Outlet_Size = df.Outlet_Size.fillna('Missing')
Sunny Barnwal
sumber
9

Pilihan lain selain yang di atas adalah:

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

Ini kurang elegan daripada respons sebelumnya untuk mean, tetapi bisa lebih pendek jika Anda ingin mengganti nol dengan beberapa fungsi kolom lainnya.

guibor
sumber
7

Panda: Bagaimana cara mengganti nilai NaN ( nan) dengan rata-rata (rata-rata), median atau statistik lainnya dari satu kolom

Katakanlah DataFrame dfAnda dan Anda memiliki satu kolom yang dipanggil nr_items. Ini adalah: df['nr_items']

Jika Anda ingin mengganti dengan NaNnilai-nilai kolom Anda df['nr_items']dengan rerata kolom :

Gunakan metode .fillna():

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

Saya telah membuat dfkolom baru yang disebut nr_item_aveuntuk menyimpan kolom baru dengan NaNnilai - nilai yang digantikan oleh meannilai kolom.

Anda harus berhati-hati saat menggunakan mean. Jika Anda memiliki outlier lebih direkomendasikan untuk menggunakanmedian

pink.slash
sumber
0

menggunakan kelas preprocessing perpustakaan 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])

Catatan: Dalam nilai parameter versi terbaru missing_valuesberubah np.nandariNaN

Shrikant Chaudhari
sumber