ค้นหาคอลัมน์สูงสุดสองคอลัมน์ขึ้นไปที่มีแพนด้า


101

ฉันมี dataframe พร้อมคอลัมน์A, B. ฉันต้องการสร้างคอลัมน์Cสำหรับทุกระเบียน / แถว:

C = max(A, B).

ฉันควรทำอย่างไร?

คำตอบ:


191

คุณจะได้รับสูงสุดดังนี้:

>>> import pandas as pd
>>> df = pd.DataFrame({"A": [1,2,3], "B": [-2, 8, 1]})
>>> df
   A  B
0  1 -2
1  2  8
2  3  1
>>> df[["A", "B"]]
   A  B
0  1 -2
1  2  8
2  3  1
>>> df[["A", "B"]].max(axis=1)
0    1
1    8
2    3

และอื่น ๆ :

>>> df["C"] = df[["A", "B"]].max(axis=1)
>>> df
   A  B  C
0  1 -2  1
1  2  8  8
2  3  1  3

หากคุณรู้ว่า "A" และ "B" เป็นคอลัมน์เดียวคุณก็สามารถหลีกเลี่ยงได้

>>> df["C"] = df.max(axis=1)

และคุณก็ใช้ได้.apply(max, axis=1)เช่นกันฉันเดา


1
.apply(max, axis=1)ช้ากว่ามาก.max(axis=1)
RajeshM

28

คำตอบของ @ DSM นั้นดีอย่างสมบูรณ์แบบในเกือบทุกสถานการณ์ปกติ แต่ถ้าคุณเป็นโปรแกรมเมอร์ประเภทที่ต้องการลงลึกกว่าระดับพื้นผิวเล็กน้อยคุณอาจสนใจที่จะรู้ว่าการเรียกใช้ฟังก์ชัน numpy บนอาร์เรย์พื้นฐาน.to_numpy()(หรือ.valuesสำหรับ <0.24) นั้นเร็วกว่าเล็กน้อยแทนโดยตรง การเรียกใช้ฟังก์ชัน (cythonized) ที่กำหนดบนอ็อบเจ็กต์ DataFrame / Series

ตัวอย่างเช่นคุณสามารถใช้ndarray.max()ตามแกนแรก

# Data borrowed from @DSM's post.
df = pd.DataFrame({"A": [1,2,3], "B": [-2, 8, 1]})
df
   A  B
0  1 -2
1  2  8
2  3  1

df['C'] = df[['A', 'B']].values.max(1)
# Or, assuming "A" and "B" are the only columns, 
# df['C'] = df.values.max(1) 
df

   A  B  C
0  1 -2  1
1  2  8  8
2  3  1  3 

หากข้อมูลของคุณมีNaNคุณจะต้องnumpy.nanmax:

df['C'] = np.nanmax(df.values, axis=1)
df

   A  B  C
0  1 -2  1
1  2  8  8
2  3  1  3 

numpy.maximum.reduceนอกจากนี้คุณยังสามารถใช้ numpy.maximumเป็นufunc (Universal Function)และufunc ทุกตัวมีreduce :

df['C'] = np.maximum.reduce(df['A', 'B']].values, axis=1)
# df['C'] = np.maximum.reduce(df[['A', 'B']], axis=1)
# df['C'] = np.maximum.reduce(df, axis=1)
df

   A  B  C
0  1 -2  1
1  2  8  8
2  3  1  3

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

np.maximum.reduceและnp.maxดูเหมือนจะมากหรือน้อยเหมือนกัน (สำหรับ DataFrames ขนาดปกติมากที่สุด) DataFrame.maxและเกิดขึ้นจะเป็นร่มเงาได้เร็วกว่า ฉันคิดว่าความแตกต่างนี้ยังคงคงที่โดยประมาณและเกิดจากค่าโสหุ้ยภายใน (การจัดตำแหน่งดัชนีการจัดการ NaNs ฯลฯ )

กราฟถูกสร้างขึ้นโดยใช้เพอร์พล็อต รหัสเปรียบเทียบสำหรับการอ้างอิง:

import pandas as pd
import perfplot

np.random.seed(0)
df_ = pd.DataFrame(np.random.randn(5, 1000))

perfplot.show(
    setup=lambda n: pd.concat([df_] * n, ignore_index=True),
    kernels=[
        lambda df: df.assign(new=df.max(axis=1)),
        lambda df: df.assign(new=df.values.max(1)),
        lambda df: df.assign(new=np.nanmax(df.values, axis=1)),
        lambda df: df.assign(new=np.maximum.reduce(df.values, axis=1)),
    ],
    labels=['df.max', 'np.max', 'np.maximum.reduce', 'np.nanmax'],
    n_range=[2**k for k in range(0, 15)],
    xlabel='N (* len(df))',
    logx=True,
    logy=True)

พิมพ์ผิดเล็กน้อย: "df ['C'] = np.maximum.reduce (df ['A', 'B']]. values, axis = 1)" ควรเป็น "df ['C'] = np.maximum ลด (df [['A', 'B']]. values, axis = 1) "
Velizar VESSELINOV
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.