找到带有熊猫的两列或更多列的最大值

我有一个数据帧与列 AB。我需要创建一个列 C,这样对于每个记录/行:

C = max(A, B).

我该怎么做呢?

229664 次浏览

你可以得到这样的最大值:

>>> 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()(或者在 < 0.24时调用 .values)数组上调用 numpy 函数比直接调用 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 都有一个 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

enter image description here

np.maximum.reducenp.max看起来差不多(对于大多数正常大小的 DataFrames)ーー而且碰巧比 DataFrame.max快一个色度。我想这种差异基本上保持不变,这是由于内部开销(索引对齐、处理 NaN 等)。

该图是使用 完美情节生成的。基准测试代码,供参考:

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)

在多列中查找 max 的方法是:

df[['A','B']].max(axis=1).max(axis=0)

例如:

df =


A      B
timestamp
2019-11-20 07:00:16  14.037880  15.217879
2019-11-20 07:01:03  14.515359  15.878632
2019-11-20 07:01:33  15.056502  16.309152
2019-11-20 07:02:03  15.533981  16.740607
2019-11-20 07:02:34  17.221073  17.195145


print(df[['A','B']].max(axis=1).max(axis=0))
17.221073

你可以使用方法 agg(aggregate) ,例如:

df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df.agg('max', 1)

产出:

0    4
1    5
2    6
dtype: int64

你可以使用多种统计数据:

df.agg(['max', 'min', 'mean'], 1)

产出:

   max  min  mean
0  4.0  1.0   2.5
1  5.0  2.0   3.5
2  6.0  3.0   4.5