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

新手上路,请多包涵

我有一个包含列的数据 A , B 。我需要创建一个列 C 这样对于每条记录/行:

C = max(A, B)

我应该怎么做呢?

原文由 Navneet 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 241
2 个回答

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

 >>> 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 发布,翻译遵循 CC BY-SA 3.0 许可协议

@DSM 的回答几乎在任何正常情况下都很好。但是如果你是那种想要比表面水平更深入一点的程序员,你可能有兴趣知道在底层调用 numpy 函数会更快一点 .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 s,您将需要 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.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.reducenp.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)

原文由 cs95 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题