pandas DataFrame: แทนที่ค่าน่านด้วยค่าเฉลี่ยของคอลัมน์


177

ฉันได้รับ DataFrame แพนด้าส่วนใหญ่เต็มไปด้วยตัวเลขจริง แต่ก็มีnanค่าน้อยเช่นกัน

ฉันจะแทนที่nans ด้วยค่าเฉลี่ยของคอลัมน์ที่พวกเขาอยู่ได้อย่างไร

คำถามนี้คล้ายกับคำถามนี้: numpy array: แทนที่ค่า 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

docstring ของfillnaบอกว่าvalueควรเป็นเซนต์คิตส์และเนวิส แต่ดูเหมือนว่าจะทำงานร่วมกับSeriesเช่นกัน หากคุณต้องการที่จะผ่าน Dict df.mean().to_dict()คุณสามารถใช้


10
df.fillna(df.mean())จะส่งคืน dataframe ใหม่ดังนั้นคุณจะต้องเขียนdf=df.fillna(df.mean())เพื่อเก็บไว้
yannis

ความคิดใด ๆ ที่ทำให้ฉันได้รับจำนวนที่ไม่ถูกต้องซึ่งหมายถึงการใช้สิ่งนี้
bernando_vialli

25
แทนที่จะเป็นเช่นนั้นdf=df.fillna(df.mean())คุณสามารถใช้df.fillna(df.mean(), inplace=True)
Anderson Pimentel

20
ข้อควรระวัง: ถ้าคุณต้องการใช้สิ่งนี้สำหรับการเรียนรู้ของเครื่อง / วิทยาศาสตร์ข้อมูล: จากมุมมองของวิทยาศาสตร์ข้อมูลมันผิดที่จะแทนที่ NA ก่อนแล้วจึงแยกเป็นรถไฟและทดสอบ ... คุณต้องแยกเป็นรถไฟและทดสอบก่อน หมายถึงบนรถไฟและจากนั้นใช้โมเดลการเตรียมประมวลผลที่เป็นรัฐนี้เพื่อทดสอบดูคำตอบที่เกี่ยวข้องกับ sklearn ด้านล่าง
เฟเบียนเวอร์เนอร์

2
@ amalik2205 เพราะมิฉะนั้นคุณกำลังรั่วไหลข้อมูลจากชุดทดสอบไปยังชุดฝึกอบรม! ลองจินตนาการว่าเป็นแบบนี้: เรามี 100 แถวข้อมูลและเราพิจารณาคอลัมน์ x 99 รายการแรกของ x คือ NA เราต้องการแยกแถว 100 ออกเป็นชุดทดสอบ สมมติว่าแถว 100 มีค่า 20 ในคอลัมน์ x จากนั้นคุณจะแทนที่รายการทั้งหมดในชุดฝึกอบรมในคอลัมน์ 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 อย่างไรก็ตามหากคุณกำลังแนะนำบางสิ่งที่แตกต่างคุณอาจต้องการชี้ให้เห็นถึงความก้าวหน้าในการทำเช่นนั้น
Dr Nisha Arora

10

หากคุณต้องการกำหนดค่าที่ขาดหายไปโดยมีค่าเฉลี่ยและคุณต้องการไปทีละคอลัมน์ก็จะเป็นการใส่ค่าเฉลี่ยของคอลัมน์นั้นเท่านั้น นี่อาจจะอ่านง่ายขึ้นอีกนิด

sub2['income'] = sub2['income'].fillna((sub2['income'].mean()))

3
โปรดให้คำอธิบายเกี่ยวกับวิธีการแก้ปัญหา
Gurwinder Singh

10

ใช้โดยตรงdf.fillna(df.mean())เพื่อเติมค่า Null ทั้งหมดด้วยค่าเฉลี่ย

หากคุณต้องการเติมค่า Null ด้วยค่าเฉลี่ยของคอลัมน์คุณสามารถใช้สิ่งนี้ได้

สมมติว่าx=df['Item_Weight']นี่Item_Weightคือชื่อคอลัมน์

ที่นี่เราได้รับมอบหมาย (เติมค่า null ของ x ด้วยค่าเฉลี่ยของ x เป็น x)

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

หากคุณต้องการเติมค่า null ด้วยสตริงให้ใช้

นี่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()))

มันมีความสวยงามน้อยกว่าคำตอบก่อนหน้าสำหรับค่าเฉลี่ย แต่อาจสั้นกว่านี้หากคุณต้องการแทนที่ค่า Null ด้วยฟังก์ชันคอลัมน์อื่น


7

Pandas: วิธีแทนที่ค่า NaN ( nan) ด้วยค่าเฉลี่ย (หมายถึง) ค่ามัธยฐานหรือสถิติอื่น ๆ ของหนึ่งคอลัมน์

Say 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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.