การแทนที่ค่าคอลัมน์ใน pandas DataFrame


141

ฉันพยายามแทนที่ค่าในหนึ่งคอลัมน์ของ dataframe คอลัมน์ ('หญิง') มีเฉพาะค่า 'หญิง' และ 'ชาย'

ฉันได้ลองทำสิ่งต่อไปนี้แล้ว:

w['female']['female']='1'
w['female']['male']='0' 

แต่รับสำเนาผลลัพธ์เดียวกันก่อนหน้านี้ทุกประการ

ฉันต้องการที่จะรับเอาท์พุทที่คล้ายกับองค์ประกอบวนรอบต่อไปนี้

if w['female'] =='female':
    w['female'] = '1';
else:
    w['female'] = '0';

ฉันดูเอกสาร gotchas ( http://pandas.pydata.org/pandas-docs/stable/gotchas.html ) แต่ไม่สามารถเข้าใจได้ว่าทำไมไม่มีอะไรเกิดขึ้น

ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชม.

คำตอบ:


259

ถ้าฉันเข้าใจถูกต้องคุณต้องการสิ่งนี้:

w['female'] = w['female'].map({'female': 1, 'male': 0})

(ที่นี่ฉันแปลงค่าเป็นตัวเลขแทนที่จะเป็นสตริงที่มีตัวเลขคุณสามารถแปลงเป็น"1"และ"0"ถ้าคุณต้องการ แต่ฉันไม่แน่ใจว่าทำไมคุณถึงต้องการมัน)

สาเหตุที่รหัสของคุณใช้งานไม่ได้เนื่องจากใช้['female']ในคอลัมน์ (ตัวที่สอง'female'ในตัวคุณw['female']['female']) ไม่ได้หมายความว่า "เลือกแถวที่มีค่าเป็น 'female'" หมายถึงการเลือกแถวที่ดัชนีเป็น 'หญิง' ซึ่งอาจไม่มีใน DataFrame ของคุณ


6
ขอบคุณ สิ่งที่ฉันกำลังมองหา ถ้าฉันจะทำแผนที่ 'female' ถึง 1 และอย่างอื่นเป็น '0' มันจะทำงานอย่างไร
สีดำ

17
ใช้สิ่งนี้เท่านั้นหากได้รับค่าทั้งหมดในคอลัมน์ในฟังก์ชันแผนที่ค่าตัวเลขที่ไม่ได้ระบุในฟังก์ชั่นแผนที่จะถูกแทนที่ด้วย Nan
จันทรา

1
ฉันขอแนะนำให้ใช้.locไวยากรณ์เพื่อหลีกเลี่ยงSettingWithCopyWarning: pandas.pydata.org/pandas-docs/stable/ ......
NickBraunagel

2
แทน. แผนที่ฉันใช้. แทนที่
JS noob

ฉันจะกำจัด '.' ได้อย่างไร จากหลายพันในคอลัมน์ที่สองหรือมากกว่าไม่สามารถคิดออก ขอบคุณมาก
M. Mariscal

115

คุณสามารถแก้ไขเซตย่อยของ dataframe ได้โดยใช้ loc:

df.loc[<row selection>, <column selection>]

ในกรณีนี้:

w.loc[w.female != 'female', 'female'] = 0
w.loc[w.female == 'female', 'female'] = 1

1
ฉันจะปรับได้อย่างไรฉันจึงไม่จำเป็นต้องเลือกแถวใด ๆ ผ่านเงื่อนไขเพียงแค่ทุกแถวในคอลัมน์ใดคอลัมน์หนึ่ง ดังนั้นเปลี่ยนเซลล์ทั้งหมดในคอลัมน์เป็นค่าเฉพาะ
Dhruv Ghulati

3
@DhruvGhulati คุณจะใช้ df.loc [:, <การเลือกคอลัมน์>]




11

คุณยังสามารถใช้applyกับ.getเช่น

w['female'] = w['female'].apply({'male':0, 'female':1}.get):

w = pd.DataFrame({'female':['female','male','female']})
print(w)

ดาต้าเฟรมw:

   female
0  female
1    male
2  female

การใช้applyเพื่อแทนที่ค่าจากพจนานุกรม:

w['female'] = w['female'].apply({'male':0, 'female':1}.get)
print(w)

ผลลัพธ์:

   female
0       1
1       0
2       1 

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


8

มีขนาดกะทัดรัดมาก:

w['female'][w['female'] == 'female']=1
w['female'][w['female'] == 'male']=0

อีกหนึ่งที่ดี:

w['female'] = w['female'].replace(regex='female', value=1)
w['female'] = w['female'].replace(regex='male', value=0)

ตัวอย่างแรกคือการจัดทำดัชนีที่ถูกโยงโซ่และถูกเตือนเนื่องจากไม่สามารถรับประกันได้ว่า df ที่ได้นั้นเป็นสำเนาหรือมุมมอง ดูการจัดทำดัชนีแบบผูกมัด
Nordle

7

อีกทางหนึ่งคือมีฟังก์ชันในตัว pd.get_dummies สำหรับการมอบหมายประเภทนี้:

w['female'] = pd.get_dummies(w['female'],drop_first = True)

สิ่งนี้จะทำให้คุณมีกรอบข้อมูลที่มีสองคอลัมน์หนึ่งคอลัมน์สำหรับแต่ละค่าที่เกิดขึ้นใน w ['female'] ซึ่งคุณทิ้งรายการแรก (เนื่องจากคุณสามารถอนุมานได้จากคอลัมน์ที่เหลือ) คอลัมน์ใหม่จะตั้งชื่อโดยอัตโนมัติเป็นสตริงที่คุณแทนที่

สิ่งนี้มีประโยชน์อย่างยิ่งหากคุณมีตัวแปรเด็ดขาดที่มีค่าที่เป็นไปได้มากกว่าสองค่า ฟังก์ชั่นนี้สร้างตัวแปรจำลองจำนวนเท่าที่จำเป็นเพื่อแยกความแตกต่างระหว่างทุกกรณี ระวังให้ดีว่าคุณไม่ได้กำหนดเฟรมข้อมูลทั้งหมดให้กับคอลัมน์เดียว แต่ถ้า w ['female'] อาจเป็น 'male', 'female' หรือ 'neutral' ให้ทำดังนี้:

w = pd.concat([w, pd.get_dummies(w['female'], drop_first = True)], axis = 1])
w.drop('female', axis = 1, inplace = True)

จากนั้นคุณจะเหลือคอลัมน์ใหม่สองคอลัมน์ที่ให้รหัสจำลองของ 'female' และคุณกำจัดคอลัมน์ด้วยสตริง


4

ใช้Series.mapกับSeries.fillna

ถ้าคอลัมน์ของคุณมีสตริงมากกว่าเพียงfemaleและmale, Series.mapจะล้มเหลวในกรณีนี้เพราะมันจะกลับมาNaNสำหรับค่าอื่น ๆ

นั่นเป็นเหตุผลที่เราต้องเชื่อมโยงกับfillna:

ตัวอย่างสาเหตุที่.mapล้มเหลว :

df = pd.DataFrame({'female':['male', 'female', 'female', 'male', 'other', 'other']})

   female
0    male
1  female
2  female
3    male
4   other
5   other
df['female'].map({'female': '1', 'male': '0'})

0      0
1      1
2      1
3      0
4    NaN
5    NaN
Name: female, dtype: object

สำหรับวิธีที่ถูกต้องเราโยงmapกับfillnaดังนั้นเราจึงเติมNaNด้วยค่าจากคอลัมน์เดิม:

df['female'].map({'female': '1', 'male': '0'}).fillna(df['female'])

0        0
1        1
2        1
3        0
4    other
5    other
Name: female, dtype: object

2

นอกจากนี้ยังมีฟังก์ชั่นที่pandasเรียกว่าfactorizeซึ่งคุณสามารถใช้เพื่อทำงานประเภทนี้โดยอัตโนมัติ ['male', 'female', 'male'] -> [0, 1, 0]มันจะแปลงป้ายไปยังหมายเลข: ดูคำตอบนี้สำหรับข้อมูลเพิ่มเติม


0

ฉันคิดว่าในคำตอบควรจะชี้ประเภทของวัตถุที่คุณได้รับในวิธีการทั้งหมดที่แนะนำข้างต้น: มันเป็น Series หรือ DataFrame

เมื่อคุณได้รับคอลัมน์ตามw.female.หรือw[[2]](โดยที่สมมติว่า 2 คือจำนวนคอลัมน์ของคุณ) คุณจะได้รับ DataFrame กลับมา ดังนั้นในกรณีนี้คุณสามารถใช้วิธี DataFrame .replaceเช่น

เมื่อคุณใช้.locหรือilocคุณได้รับกลับชุดและชุดที่ไม่ได้มี.replaceวิธีการดังนั้นคุณควรใช้วิธีการเช่นapply, mapและอื่น ๆ

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