Temukan jumlah maksimal dua atau lebih kolom dengan panda

105

Saya memiliki dataframe dengan kolom A, B. Saya perlu membuat kolom Csedemikian rupa untuk setiap record / baris:

C = max(A, B).

Bagaimana saya harus melakukan ini?

Navneet
sumber

Jawaban:

198

Anda bisa mendapatkan hasil maksimal seperti ini:

>>> 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

sehingga:

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

Jika Anda tahu bahwa "A" dan "B" adalah satu-satunya kolom, Anda bahkan dapat melakukannya

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

Dan Anda juga bisa menggunakannya .apply(max, axis=1), saya rasa.

DSM
sumber
2
.apply(max, axis=1)jauh lebih lambat daripada.max(axis=1)
RajeshM
30

@ Jawaban DSM baik-baik saja di hampir semua skenario normal. Tetapi jika Anda adalah tipe programmer yang ingin membahas lebih dalam dari level permukaan, Anda mungkin tertarik untuk mengetahui bahwa memanggil fungsi numpy pada array yang mendasari .to_numpy()(atau .valuesuntuk <0,24) lebih cepat daripada langsung memanggil fungsi (cythonized) yang ditentukan pada objek DataFrame / Series.

Misalnya, Anda dapat menggunakan ndarray.max()sepanjang sumbu pertama.

# 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 

Jika data Anda memiliki NaNs, Anda akan membutuhkan 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 

Anda juga bisa menggunakan numpy.maximum.reduce. numpy.maximumadalah ufunc (Fungsi Universal) , dan setiap ufunc memilikireduce :

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

masukkan deskripsi gambar di sini

np.maximum.reducedan np.maxtampak lebih atau kurang sama (untuk sebagian besar DataFrames berukuran normal) —dan kebetulan lebih cepat dari DataFrame.max. Saya membayangkan perbedaan ini kira-kira tetap konstan, dan disebabkan oleh overhead internal (penyelarasan pengindeksan, penanganan NaN, dll).

Grafik dibuat menggunakan perfplot . Kode pembandingan, untuk referensi:

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)
cs95
sumber
Kesalahan ketik kecil: "df ['C'] = np.maximum.reduce (df ['A', 'B']]. Values, axis = 1)" harus "df ['C'] = np.maximum. mengurangi (df [['A', 'B']]. values, axis = 1) "
Velizar VESSELINOV