【问题标题】:Find the max of two or more columns with pandas用熊猫查找两列或多列的最大值
【发布时间】:2012-08-23 13:06:15
【问题描述】:

我有一个包含A,B 列的数据框。我需要为每个记录/行创建一个列C

C = max(A, B).

我该怎么做呢?

【问题讨论】:

    标签: python dataframe pandas


    【解决方案1】:

    要在多个列中找到最大值:

    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
    

    【讨论】:

      【解决方案2】:

      @DSM 的答案在几乎任何正常情况下都非常好。但如果你是那种想要比表面更深入一点的程序员,你可能有兴趣知道在底层.to_numpy()(或.values for

      例如,您可以沿第一个轴使用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 
      

      如果您的数据有NaNs,则需要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 (Universal Function),而every ufunc has a 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)——并且恰好比 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)"
      【解决方案3】:

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

      >>> 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)

      【讨论】:

      • .apply(max, axis=1).max(axis=1) 慢很多
      猜你喜欢
      • 2022-10-16
      • 1970-01-01
      • 2018-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多