【问题标题】:Pandas: Difference between largest and smallest value within group熊猫:组内最大值和最小值之间的差异
【发布时间】:2017-03-04 04:29:48
【问题描述】:

给定一个看起来像这样的数据框

GROUP VALUE
  1     5
  2     2
  1     10
  2     20
  1     7

我想计算每组中最大值和最小值之间的差异。也就是说,结果应该是

GROUP   DIFF
  1      5
  2      18

在 Pandas 中有什么简单的方法可以做到这一点?

对于具有大约 200 万行和 100 万组的数据框,在 Pandas 中执行此操作的快速方法是什么?

【问题讨论】:

    标签: python pandas numpy


    【解决方案1】:

    使用@unutbu 的df

    每个时间
    unutbu 的解决方案优于大型数据集

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame({'GROUP': [1, 2, 1, 2, 1], 'VALUE': [5, 2, 10, 20, 7]})
    
    df.groupby('GROUP')['VALUE'].agg(np.ptp)
    
    GROUP
    1     5
    2    18
    Name: VALUE, dtype: int64
    

    np.ptp docs 返回数组的范围


    时机
    df

    df
    df = pd.DataFrame(dict(GROUP=np.arange(1000000) % 100, VALUE=np.random.rand(1000000)))

    df
    很多组
    df = pd.DataFrame(dict(GROUP=np.arange(1000000) % 10000, VALUE=np.random.rand(1000000)))

    【讨论】:

    • 很长一段时间我一直在想为什么pandas没有range方法。很高兴知道 numpy 有它。
    • 我在这里遗漏了什么吗?似乎 np.ptp 方法仅在“小 df”情况下最快。在其他情况下,.agg([max],[min]).diff(axis=1) 方法的性能明显更好。
    • @HeavyBreathing 你没有错过任何事情。我提供了一个替代解决方案,但正在验证另一个海报的解决方案。
    【解决方案2】:

    groupby/agg 通常在您利用 'max''min' 等内置聚合器时表现最佳。所以要得到差值,首先计算maxmin然后减去:

    import pandas as pd
    df = pd.DataFrame({'GROUP': [1, 2, 1, 2, 1], 'VALUE': [5, 2, 10, 20, 7]})
    result = df.groupby('GROUP')['VALUE'].agg(['max','min'])
    result['diff'] = result['max']-result['min']
    print(result[['diff']])
    

    产量

           diff
    GROUP      
    1         5
    2        18
    

    【讨论】:

    • 老实说,我很惊讶这比agg(np.ptp) 好得多,尤其是在大量组中!
    • 如果我想对多列中的每一列执行此操作,而不仅仅是一个 ('VALUE')?
    • @CPBL:如果您想为df 的所有列找到minmax(每个GROUP),那么只需删除['VALUE']。也就是说,使用df.groupby('GROUP').agg(['max', 'min'])。如果您希望在GROUP 中为某些但不是所有列找到minmax,请首先限制dfdf[['GROUP','VALUE1','VALUE2']].groupby('GROUP').agg(['max','min'])
    • 谢谢。是否有一种方法可以获取差异? (不使用 np.ptp,因为我实际上想要与 agg(['last','first']) 的签名差异)
    • @CPBL:你可以使用df.groupby('GROUP').agg(['last','first']).stack(level=0).diff(axis=1).unstack(-1)['last']。但我不觉得这特别可读。也许使用 3 行 result = df.groupby('GROUP').agg(['last','first'])result = result.reorder_levels([1,0], axis=1)result['last'] - result['first'] 会更好。
    【解决方案3】:

    注意:这将完成工作,但@piRSquared's answer 有更快的方法。

    您可以使用groupby()min()max()

    df.groupby('GROUP')['VALUE'].apply(lambda g: g.max() - g.min())
    

    【讨论】:

      猜你喜欢
      • 2020-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-03
      • 2020-04-30
      • 1970-01-01
      • 2017-07-25
      • 2021-01-24
      相关资源
      最近更新 更多