การสร้างคอลัมน์ใหม่ตามเงื่อนไข if-elif-else


100

ฉันมี DataFrame df:

    A    B
a   2    2 
b   3    1
c   1    3

ฉันต้องการสร้างคอลัมน์ใหม่ตามเกณฑ์ต่อไปนี้:

ถ้าแถว A == B: 0

ถ้าแถวA > B: 1

ถ้าแถว A < B: -1

ดังนั้นตารางด้านบนควรเป็น:

    A    B    C
a   2    2    0
b   3    1    1
c   1    3   -1 

สำหรับif elseกรณีทั่วไปที่ฉันทำnp.where(df.A > df.B, 1, -1)แพนด้ามีไวยากรณ์พิเศษสำหรับการแก้ปัญหาของฉันด้วยขั้นตอนเดียวหรือไม่ (โดยไม่จำเป็นต้องสร้างคอลัมน์ใหม่ 3 คอลัมน์แล้วรวมผลลัพธ์)


คุณสามารถกำหนดฟังก์ชันและส่งผ่านไปapplyและการตั้งค่าaxis=1จะใช้งานได้ไม่แน่ใจว่าฉันสามารถคิดถึงการดำเนินการที่จะให้สิ่งที่คุณต้องการ
EdChum

โซลูชันของคุณหมายถึงการสร้าง 3 คอลัมน์และรวมไว้ใน 1 คอลัมน์หรือคุณมีบางอย่างที่แตกต่างออกไป?
nutship

คุณพูดว่า "สร้าง 3 คอลัมน์" อยู่เรื่อย ๆ แต่ฉันไม่แน่ใจว่าคุณหมายถึงอะไร
DSM

1
@DSM ได้ตอบคำถามนี้แล้ว แต่ฉันหมายถึงบางอย่างเช่นdf['C']=df.apply(myFunc(row), axis=1)ที่ myFunc ทำในสิ่งที่คุณต้องการสิ่งนี้ไม่เกี่ยวข้องกับการสร้าง '3 คอลัมน์'
EdChum

คำตอบ:


146

ในการทำให้แนวทางบางอย่างที่วางไว้ข้างต้นเป็นทางการ:

สร้างฟังก์ชันที่ทำงานบนแถวของดาต้าเฟรมของคุณดังนี้:

def f(row):
    if row['A'] == row['B']:
        val = 0
    elif row['A'] > row['B']:
        val = 1
    else:
        val = -1
    return val

จากนั้นนำไปใช้กับดาต้าเฟรมของคุณที่ส่งผ่านในaxis=1ตัวเลือก:

In [1]: df['C'] = df.apply(f, axis=1)

In [2]: df
Out[2]:
   A  B  C
a  2  2  0
b  3  1  1
c  1  3 -1

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

แก้ไข

นี่คือเวอร์ชัน vectorized

df['C'] = np.where(
    df['A'] == df['B'], 0, np.where(
    df['A'] >  df['B'], 1, -1)) 

1
ขอบคุณฉันเริ่มต้นด้วยแพนด้าและสิ่งนี้มีประโยชน์มาก +1
nutship

4
จะเกิดอะไรขึ้นถ้าฉันต้องการส่งผ่านพารามิเตอร์อื่นพร้อมกับแถวในฟังก์ชัน? ถ้าฉันทำมันบอกว่า row ไม่ได้กำหนด ..
prashanth manohar

3
คุณต้องใช้argsพารามิเตอร์ของ.applyฟังก์ชัน: pandas.pydata.org/pandas-docs/stable/generated/…
Zelazny7

1
ฉันเป็นผู้ใช้ SAS เก่าที่เรียนภาษา Python และมีช่วงการเรียนรู้อย่างแน่นอน! :-) ตัวอย่างเช่นโค้ดด้านบนสามารถเขียนใน SAS ได้ว่าdata df; set df; if A=B then C=0; else if A>B then C=1; else C=-1; run;หรูหราและเรียบง่ายมาก
RobertF

1
คำตอบที่ชัดเจน
Sahil Nagpal

51
df.loc[df['A'] == df['B'], 'C'] = 0
df.loc[df['A'] > df['B'], 'C'] = 1
df.loc[df['A'] < df['B'], 'C'] = -1

แก้ไขได้ง่ายโดยใช้การจัดทำดัชนี บรรทัดแรกของโค้ดจะอ่านเช่นนั้นหากคอลัมน์Aเท่ากับคอลัมน์ให้Bสร้างและตั้งค่าคอลัมน์Cเท่ากับ 0


17

สำหรับความสัมพันธ์นี้คุณสามารถใช้np.sign:

>>> df["C"] = np.sign(df.A - df.B)
>>> df
   A  B  C
a  2  2  0
b  3  1  1
c  1  3 -1

6

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

ให้บอกว่าด้านบนคือดาต้าเฟรมเดิมของคุณและคุณต้องการเพิ่มคอลัมน์ใหม่ 'เก่า'

ถ้าอายุมากกว่า 50 เราจะถือว่าอายุมากกว่า = ใช่เป็นเท็จ

ขั้นตอนที่ 1: รับดัชนีของแถวที่มีอายุมากกว่า 50

row_indexes=df[df['age']>=50].index

ขั้นตอนที่ 2: การใช้. loc เราสามารถกำหนดค่าใหม่ให้กับคอลัมน์

df.loc[row_indexes,'elderly']="yes"

เช่นเดียวกันสำหรับอายุต่ำกว่า 50 ปี

row_indexes=df[df['age']<50].index

df[row_indexes,'elderly']="no"

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