Panda veri çerçevesinin bir sütununda tüm NaN değerlerini Zeros ile nasıl değiştirebilirim?


460

Aşağıdaki gibi bir veri çerçevem ​​var

      itm Date                  Amount 
67    420 2012-09-30 00:00:00   65211
68    421 2012-09-09 00:00:00   29424
69    421 2012-09-16 00:00:00   29877
70    421 2012-09-23 00:00:00   30990
71    421 2012-09-30 00:00:00   61303
72    485 2012-09-09 00:00:00   71781
73    485 2012-09-16 00:00:00     NaN
74    485 2012-09-23 00:00:00   11072
75    485 2012-09-30 00:00:00  113702
76    489 2012-09-09 00:00:00   64731
77    489 2012-09-16 00:00:00     NaN

Miktar sütununa .appl işlevini uygulamaya çalıştığımda aşağıdaki hatayı alıyorum.

ValueError: cannot convert float NaN to integer

Ben Matematik Modülünden .isnan kullanarak bir işlev uygulamayı denedim Ben pandalar .replace özniteliğini denedim. Pandalar 0.9 .sparse veri özniteliğini denedim Ayrıca NaN == NaN deyimi bir işlevde denedim. Bu makaleye de baktım NA veri bir R veri çerçevesinde sıfır ile nasıl değiştirebilirim? diğer makalelere bakarken. Denediğim tüm yöntemler NaN'yi çalışmadı veya tanımıyor. Herhangi bir İpucu veya çözüm takdir edilecektir.


Uyguladığınız veri çerçevesi yeniden örneklenirse veya loc işlevi ile dilimlenirse, tek sorun df.fill.na () çalışmaz
Prince Agarwal

Yanıtlar:


754

Bunu DataFrame.fillna()senin için yapacağına inanıyorum .

Bir veri çerçevesi ve bir Seri için Dokümanlar'a bağlantı .

Misal:

In [7]: df
Out[7]: 
          0         1
0       NaN       NaN
1 -0.494375  0.570994
2       NaN       NaN
3  1.876360 -0.229738
4       NaN       NaN

In [8]: df.fillna(0)
Out[8]: 
          0         1
0  0.000000  0.000000
1 -0.494375  0.570994
2  0.000000  0.000000
3  1.876360 -0.229738
4  0.000000  0.000000

NaN'leri yalnızca bir sütuna doldurmak için yalnızca o sütunu seçin. bu durumda aslında df içeriğini değiştirmek için inplace = True kullanıyorum.

In [12]: df[1].fillna(0, inplace=True)
Out[12]: 
0    0.000000
1    0.570994
2    0.000000
3   -0.229738
4    0.000000
Name: 1

In [13]: df
Out[13]: 
          0         1
0       NaN  0.000000
1 -0.494375  0.570994
2       NaN  0.000000
3  1.876360 -0.229738
4       NaN  0.000000

DÜZENLE:

A'yı önlemek SettingWithCopyWarningiçin yerleşik sütuna özgü işlevselliği kullanın:

df.fillna({1:0}, inplace=True)

1
df[1]Orijinal DF'nin bir kopyası değil, bir görünüm olduğu garanti ediliyor mu? Açıkçası, bunun bir kopyası olduğu nadir bir durum varsa, süper zahmetli bir hataya neden olur. Panda belgelerinde bununla ilgili açık bir ifade var mı?
maksimum

@max Buna bakın, sorunuza cevap verebilir: stackoverflow.com/questions/23296282/…
Aman

Teşekkürler. Anladığım kadarıyla bu cevapta "setler dizini" en dıştaki indeksleme işlemi (atamadan hemen önce yürütülür. Bu nedenle, yalnızca tek bir dizinleyici kullanan herhangi bir atamanın güvenli olduğu garanti edilir ve kodunuzu güvenli kılar?
max


1
son örnek bir SettingWithCopyWarning atar
Sip

124

Dilimlemenin bir görünüm veya kopya döndürdüğü garanti edilmez. Yapabilirsin

df['column'] = df['column'].fillna(value)

14
Sadece "inplace = True" problemini keşfettim. Bu cevap sorunu önlüyor ve bence sunulan en temiz çözüm.
TimCera

48

Şunu replacedeğiştirmek NaNiçin kullanabilirsiniz 0:

import pandas as pd
import numpy as np

# for column
df['column'] = df['column'].replace(np.nan, 0)

# for whole dataframe
df = df.replace(np.nan, 0)

# inplace
df.replace(np.nan, 0, inplace=True)

Sadece yerini alacak NaNmı? ya da nerede NAveya NaNbenzeri değer yerini alacak df.fillna(0)? Ben sadece var olduğunda NaNve değil değeri yerine çözüm arıyorumNA
Shyam Bhimani

1
@ShyamBhimani sadece NaNyani np.isnangerçek değerlerini değiştirmelidir
Anton Protopopov

23

Ben sadece insanlar hala buraya geliyor gibi bir güncelleme / özel durum biraz sağlamak istedim. Çok endeksli veya başka bir dizin dilimleyici kullanıyorsanız, inplace = True seçeneği seçtiğiniz dilimi güncellemek için yeterli olmayabilir. Örneğin, 2x2 seviyeli bir çoklu dizinde bu, hiçbir değeri değiştirmez (panda 0.15'ten itibaren):

idx = pd.IndexSlice
df.loc[idx[:,mask_1],idx[mask_2,:]].fillna(value=0,inplace=True)

"Sorun" zincirleme orijinal veri çerçevesini güncelleme dolgu yeteneğini bozuyor olmasıdır. “Sorun” u tırnak içine aldım çünkü tasarım kararlarının belirli durumlarda bu zincirler aracılığıyla yorumlanmamasına yol açan iyi sebepler var. Ayrıca, bu karmaşık bir örnektir (ben gerçekten içine koştu rağmen), ama aynı dilim nasıl bağlı olarak daha az dizin düzeyleri için geçerli olabilir.

Çözüm DataFrame.update:

df.update(df.loc[idx[:,mask_1],idx[[mask_2],:]].fillna(value=0))

Bu bir satırdır, makul derecede iyi okur (bir çeşit) ve ara değişkenler veya döngülerle gereksiz karışıklıkları ortadan kaldırırken, istediğiniz herhangi bir çok seviyeli dilime dolgu uygulamanızı sağlar!

Herkes bu işe yaramaz yerler bulabilirsiniz yorumlarda gönderin, ben onunla uğraşmak ve kaynağa bakıyorum ve en azından benim çok dizinli dilim sorunları çözmek gibi görünüyor.


21

Aşağıdaki kod benim için çalıştı.

import pandas

df = pandas.read_csv('somefile.txt')

df = df.fillna(0)

7

Eksik değerleri doldurmanın kolay yolu: -

dize sütunlarını doldurma : dize sütunları eksik değerlere ve NaN değerlerine sahip olduğunda.

df['string column name'].fillna(df['string column name'].mode().values[0], inplace = True)

sayısal sütunları doldurma : sayısal sütunlarda eksik değerler ve NaN değerleri olduğunda.

df['numeric column name'].fillna(df['numeric column name'].mean(), inplace = True)

NaN'yi sıfır ile doldurma:

df['column name'].fillna(0, inplace = True)

5

Tüm DF'yi bir oneValue ile doldurmak yerine, DataFrame'deki belirli sütunların NaN değerlerini doldurmak için sözlükler de kullanabilirsiniz.

import pandas as pd

df = pd.read_excel('example.xlsx')
df.fillna( {
        'column1': 'Write your values here',
        'column2': 'Write your values here',
        'column3': 'Write your values here',
        'column4': 'Write your values here',
        .
        .
        .
        'column-n': 'Write your values here'} , inplace=True)

Bu OP'nin sorusuna geliştirici amaçlı bir çözümdür.
johnDanger

4

resim açıklamasını buraya girin

AmountYukarıdaki tabloda belirli bir sütun dikkate alındığında tamsayı tipindedir. Aşağıdaki bir çözüm olacaktır:

df['Amount'] = df.Amount.fillna(0).astype(int)

Benzer şekilde, çeşitli veri türleriyle doldurabilirsiniz float,str vb.

Özellikle, aynı sütunun çeşitli değerlerini karşılaştırmak için veri tipini düşünürüm.


2

Pandalardaki na değerlerini değiştirmek için

df['column_name'].fillna(value_to_be_replaced,inplace=True)

eğer inplace = False, df'yi (veri çerçevesi) güncellemek yerine değiştirilen değerleri döndürür.


1

Bir panda veri çerçevesine dönüştürecek olursanız, bunu kullanarak da yapabilirsiniz fillna.

import numpy as np
df=np.array([[1,2,3, np.nan]])

import pandas as pd
df=pd.DataFrame(df)
df.fillna(0)

Bu, aşağıdakileri döndürür:

     0    1    2   3
0  1.0  2.0  3.0 NaN
>>> df.fillna(0)
     0    1    2    3
0  1.0  2.0  3.0  0.0

1

Öncelikle iki seçenek vardır; yalnızca sayısal değiştirmelerle (sütunlar arasında) NaN / np.nan değerinin doldurulması veya doldurulması durumunda :

df['Amount'].fillna(value=None, method= ,axis=1,) yeterli:

Belgelerden:

değer: delikleri doldurmak için kullanılacak skaler, dikte, Seri veya DataFrame Değeri (örn. 0), dönüşümlü olarak her bir dizin (Seri için) veya sütun (DataFrame için) için hangi değerin kullanılacağını belirten bir değer / Seri / DataFrame . (dict / Series / DataFrame içinde olmayan değerler doldurulmaz). Bu değer bir liste olamaz.

Bu, 'dizelerin' veya 'sabitlerin' artık kullanılmasına izin verilmediği anlamına gelir.

Daha özel uyarlamalar için SimpleImputer () kullanın :

from sklearn.impute import SimpleImputer
si = SimpleImputer(strategy='constant', missing_values=np.nan, fill_value='Replacement_Value')
df[['Col-1', 'Col-2']] = si.fit_transform(X=df[['C-1', 'C-2']])

0

Farklı sütunlardaki nan'i farklı yollarla değiştirmek için:

   replacement= {'column_A': 0, 'column_B': -999, 'column_C': -99999}
   df.fillna(value=replacement)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.