Saya memiliki dataframe dengan kolom A
, B
. Saya perlu membuat kolom C
sedemikian rupa untuk setiap record / baris:
C = max(A, B)
.
Bagaimana saya harus melakukan ini?
Jawaban:
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.
@ 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 .values
untuk <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 NaN
s, 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.maximum
adalah 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
np.maximum.reduce
dan np.max
tampak 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)
.apply(max, axis=1)
jauh lebih lambat daripada.max(axis=1)