ฉันจะแทนที่ค่า NaN ทั้งหมดด้วย Zeros ในคอลัมน์ของ pandas dataframe ได้อย่างไร


460

ฉันมีชื่อไฟล์ดังต่อไปนี้

      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

เมื่อฉันพยายามใช้ฟังก์ชั่นไปยังคอลัมน์จำนวนฉันได้รับข้อผิดพลาดต่อไปนี้

ValueError: cannot convert float NaN to integer

ฉันได้ลองใช้ฟังก์ชั่นโดยใช้. isnan จาก Math Module ฉันลองใช้ pandas .replace attribute แล้วฉันได้ลองใช้ data .sparse data จาก pandas 0.9 ฉันได้ลองถ้า NaN == NaN ในฟังก์ชัน ฉันได้ดูบทความนี้ฉันจะแทนที่ค่า NA ด้วยค่าศูนย์ใน R dataframe ได้อย่างไร ในขณะที่ดูบทความอื่น ๆ วิธีการทั้งหมดที่ฉันลองใช้ไม่ทำงานหรือไม่รู้จัก NaN คำแนะนำหรือแนวทางแก้ไขใด ๆ จะได้รับการชื่นชม


ปัญหาเพียงอย่างเดียวคือ df.fill.na () ไม่ทำงานหากกรอบข้อมูลที่คุณใช้ถูกปรับใหม่หรือถูกตัดผ่านฟังก์ชั่น loc
เจ้าชาย Agarwal

คำตอบ:


754

ฉันเชื่อว่าDataFrame.fillna()จะทำเพื่อคุณ

เชื่อมโยงไปยังเอกสารสำหรับdataframeและซีรีส์

ตัวอย่าง:

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 ในคอลัมน์เดียวให้เลือกเฉพาะคอลัมน์นั้น ในกรณีนี้ฉันใช้ inplace = True เพื่อเปลี่ยนเนื้อหาของ df

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

แก้ไข:

หากต้องการหลีกเลี่ยง a SettingWithCopyWarningให้ใช้ฟังก์ชันการทำงานเฉพาะคอลัมน์ในตัว:

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

1
มันรับประกันได้หรือไม่ว่าdf[1]เป็นมุมมองแทนที่จะเป็นสำเนาของ DF ดั้งเดิม เห็นได้ชัดว่าหากมีสถานการณ์ที่หายากที่มันเป็นสำเนามันจะทำให้เกิดข้อผิดพลาดที่ยากมาก มีคำชี้แจงที่ชัดเจนเกี่ยวกับสิ่งนั้นในเอกสารของแพนด้าหรือไม่?
สูงสุด

@max ดูสิ่งนี้อาจตอบคำถามของคุณ: stackoverflow.com/questions/23296282/…
Aman

ขอบคุณ ฉันเข้าใจที่ถูกต้องว่าในคำตอบว่า "ทำดัชนีที่ชุด" คือการดำเนินงานการจัดทำดัชนีนอกสุด (ดำเนินการก่อนที่จะได้รับมอบหมายดังนั้นการมอบหมายใด ๆ ที่เพียงใช้ดัชนีเดียวรับประกันได้ว่าจะปลอดภัยทำให้ปลอดภัยรหัสของคุณ.
สูงสุด

1
ทำไมสิ่งนี้ถึงไม่ทำงานสำหรับฉัน ดู: stackoverflow.com/questions/39452095/how-to-fillna-with-value-0
displayname

1
ตัวอย่างสุดท้ายจะพ่น SettingWithCopyWarning
Sip

124

ไม่รับประกันว่าการแบ่งส่วนจะคืนค่ามุมมองหรือสำเนา คุณทำได้

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

14
เพิ่งค้นพบปัญหา "inplace = True" คำตอบนี้หลีกเลี่ยงปัญหาและฉันคิดว่าเป็นทางออกที่สะอาดที่สุดที่นำเสนอ
TimCera

48

คุณสามารถใช้replaceเพื่อเปลี่ยนNaNเป็น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)

มันจะแทนที่เท่านั้นNaNหรือ หรือมันจะแทนที่ค่าที่NAหรือNaNชอบdf.fillna(0)? ฉันกำลังมองหาวิธีการแก้ปัญหาซึ่งจะแทนที่เฉพาะค่าที่มีNaNและไม่ใช่NA
Shyam Bhimani

1
@ShyamBhimani ควรแทนที่เฉพาะNaNค่าที่np.isnanเป็นจริง
Anton Protopopov

23

ฉันแค่ต้องการให้มีการอัพเดท / กรณีพิเศษเล็กน้อยเพราะดูเหมือนว่าคนยังมาที่นี่ หากคุณใช้หลายดัชนีหรือใช้ตัวแบ่งส่วนดัชนีตัวเลือก inplace = True อาจไม่เพียงพอที่จะอัปเดตส่วนที่คุณเลือก ตัวอย่างเช่นในดัชนีหลายระดับระดับ 2x2 สิ่งนี้จะไม่เปลี่ยนค่าใด ๆ (ณ pandas 0.15):

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

"ปัญหา" คือการผูกมัดแบ่งความสามารถในการเติมเพื่ออัปเดตฐานข้อมูลดั้งเดิม ฉันใส่ "ปัญหา" ไว้ในเครื่องหมายคำพูดเนื่องจากมีเหตุผลที่ดีสำหรับการตัดสินใจออกแบบที่นำไปสู่การไม่ตีความผ่านเครือข่ายเหล่านี้ในบางสถานการณ์ นอกจากนี้นี่เป็นตัวอย่างที่ซับซ้อน (แม้ว่าฉันจะพบเจอจริง ๆ ) แต่สิ่งเดียวกันอาจนำไปใช้กับดัชนีในระดับที่น้อยลงโดยขึ้นอยู่กับว่าคุณจะหั่นส่วนไหน

การแก้ปัญหาคือ DataFrame.update:

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

มันเป็นหนึ่งบรรทัดอ่านได้ดีพอสมควร (เรียงลำดับ) และกำจัดสิ่งที่ไม่จำเป็นโดยไม่จำเป็นกับตัวแปรกลางหรือลูปในขณะที่อนุญาตให้คุณใช้ Fillna กับชิ้นหลายระดับที่คุณชอบ!

หากใครสามารถหาสถานที่ที่ไม่สามารถใช้งานได้โปรดโพสต์ในความคิดเห็นฉันได้ยุ่งกับมันและมองไปที่แหล่งที่มาและดูเหมือนว่าจะแก้ปัญหาชิ้นดัชนีหลายอย่างน้อยของฉัน



7

วิธีง่ายๆในการเติมค่าที่หายไป: -

การกรอก คอลัมน์สตริง:เมื่อคอลัมน์สตริงมีค่าที่ขาดหายไปและค่า NaN

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

การกรอก คอลัมน์ตัวเลข:เมื่อคอลัมน์ตัวเลขมีค่าที่ขาดหายไปและค่า NaN

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

เติม NaN ด้วยศูนย์:

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

5

คุณยังสามารถใช้พจนานุกรมเพื่อเติมค่า NaN ของคอลัมน์เฉพาะใน DataFrame แทนการเติม DF ทั้งหมดด้วยค่าหนึ่งค่า

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)

นี่คือทางออกที่นักพัฒนาต้องการสำหรับคำถามของ OP
johnDanger

4

ป้อนคำอธิบายรูปภาพที่นี่

พิจารณาคอลัมน์เฉพาะAmountในตารางข้างต้นเป็นประเภทจำนวนเต็ม ต่อไปนี้จะเป็นวิธีแก้ปัญหา:

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

ทำนองเดียวกันคุณสามารถกรอกด้วยข้อมูลต่างๆประเภทชอบfloat,strและอื่น ๆ

โดยเฉพาะฉันจะพิจารณาประเภทข้อมูลเพื่อเปรียบเทียบค่าต่างๆของคอลัมน์เดียวกัน



1

หากคุณกำลังจะแปลงเป็นหมีแพนด้า dataframe fillnaคุณยังสามารถบรรลุนี้โดยใช้

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

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

สิ่งนี้จะคืนค่าต่อไปนี้:

     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

มีสองตัวเลือกเป็นหลัก; ในกรณีที่ใส่เข้าไปหรือเติมค่าที่หายไปNaN / np.nanด้วยการแทนที่เป็นตัวเลขเท่านั้น (ข้ามคอลัมน์):

df['Amount'].fillna(value=None, method= ,axis=1,) เพียงพอแล้ว:

จากเอกสาร:

ค่า: scalar, dict, Series หรือ DataFrame Value เพื่อใช้เติมหลุม (เช่น 0), สลับ dict / Series / DataFrame ของค่าที่ระบุค่าที่จะใช้สำหรับแต่ละดัชนี (สำหรับ Series) หรือคอลัมน์ (สำหรับ DataFrame) . (ค่าที่ไม่ได้อยู่ใน dict / Series / DataFrame จะไม่ถูกเติม) ค่านี้ไม่สามารถเป็นรายการได้

ซึ่งหมายความว่า 'สตริง' หรือ 'ค่าคงที่' จะไม่ได้รับอนุญาตให้ใส่เข้าไปอีก

สำหรับความเชี่ยวชาญเพิ่มเติมให้ใช้SimpleImputer () :

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

หากต้องการแทนที่น่านในคอลัมน์ต่างๆด้วยวิธีต่างๆ:

   replacement= {'column_A': 0, 'column_B': -999, 'column_C': -99999}
   df.fillna(value=replacement)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.