パンダで最大2つ以上の列を見つける


100

私は列を持つデータフレームを持っていますABCすべてのレコード/行に対して次のような列を作成する必要があります。

C = max(A, B)

どうすればこれを行うことができますか?

回答:


190

次のように最大値を取得できます。

>>> 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の答えは、ほとんどすべての通常のシナリオで完全に問題ありません。しかし、あなたが表面レベルよりも少し深く行きたいタイプのプログラマーなら、基礎となる.to_numpy()(または.values直接ではなく<0.24)配列で DataFrame / Seriesオブジェクトで定義された(cythonized)関数を呼び出します。

たとえば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.reducenumpy.maximumufunc(ユニバーサル関数)であり、すべての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、多かれ少なかれ(ほとんどの通常の大きさのデータフレームのために)同じであること-と日陰より速いことが起こるように見えますDataFrame.max。この違いはほぼ一定であり、内部オーバーヘッド(インデックスの配置、NaNの処理など)によるものだと思います。

グラフはperfplotを使用して生成されました。参考のためのベンチマークコード:

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である必要があります。 reduce(df [['A'、 'B']]。values、axis = 1) "
Velizar VESSELINOV
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.