私は列を持つデータフレームを持っていますA
、B
。C
すべてのレコード/行に対して次のような列を作成する必要があります。
C = max(A, B)
。
どうすればこれを行うことができますか?
回答:
次のように最大値を取得できます。
>>> 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)
と思います。
@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.reduce
。numpy.maximum
はufunc(ユニバーサル関数)であり、すべての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)
.apply(max, axis=1)
よりもはるかに遅い.max(axis=1)