【问题标题】:Pandas - Compare value current year to those of all previous years by group and return True if it is the Cumulative MinimumPandas - 按组比较当前年份的值与以前所有年份的值,如果是累积最小值则返回 True
【发布时间】:2020-10-07 22:58:01
【问题描述】:

我有一个具有以下结构的 Pandas 数据框

id    date         num        
243   2014-12-01   3
234   2014-12-01   2
243   2015-12-01   2
234   2016-12-01   4
243   2016-12-01   6
234   2017-12-01   5
243   2018-12-01   7
234   2018-12-01   10
243   2019-12-01   1
234   2019-12-01   12
243   2020-12-01   15
234   2020-12-01   5

如果字段 num 小于往年的任何值(对于每个 id >)。例如,id 243 和 date 2019-12-01 的值为 1。在这种情况下,新字段 flag 将假定为 True,因为没有值id 243 的前几年较小。预期的数据框应如下所示:

id    date         num  flag         
243   2014-12-01   3      -
234   2014-12-01   2      -
243   2015-12-01   2      True
234   2016-12-01   4      False
243   2016-12-01   6      False
234   2017-12-01   5      False
243   2018-12-01   7      False
234   2018-12-01   10      False
243   2019-12-01   1      True
234   2019-12-01   12      False
243   2020-12-01   15      False
234   2020-12-01   5      False

我一直在寻找一种解决方案,让我可以将每一行与前几年的行进行比较。有什么建议如何将每一行的值与几年前的值进行比较?

谢谢

【问题讨论】:

    标签: python pandas


    【解决方案1】:
    1. 使用.cummin按组获取累计最小值
    2. 使用.cumcount 将每个组的第一个值返回为-np.where

    df['flag'] = (df['num'] == df.groupby(['id'])['num'].transform('cummin'))
    df['flag'] = np.where(df.groupby('id').cumcount() == 0, '-', df['flag'])
    df
    Out[1]: 
         id       date  num   flag
    0   243 2014-12-01    3      -
    1   234 2014-12-01    2      -
    2   243 2015-12-01    2   True
    3   234 2016-12-01    4  False
    4   243 2016-12-01    6  False
    5   234 2017-12-01    5  False
    6   243 2018-12-01    7  False
    7   234 2018-12-01   10  False
    8   243 2019-12-01    1   True
    9   234 2019-12-01   12  False
    10  243 2020-12-01   15  False
    11  234 2020-12-01    5  False
    

    小提示:除了np.where(),您还可以使用:

    df['flag'] = df['flag'].where(df.groupby('id').cumcount() != 0, '-')
    

    基本上做同样的事情。

    在其中一行代码中:

    (df.num == df.groupby('id').num.cummin()).where(df.groupby('id').cumcount() != 0, '-')
    

    【讨论】:

      【解决方案2】:

      让我们使用cummin + duplicatedwhere

      (df['num']==df.groupby('id')['num'].cummin()).where(df.id.duplicated(),'-')
      0         -
      1         -
      2      True
      3     False
      4     False
      5     False
      6     False
      7     False
      8      True
      9     False
      10    False
      11    False
      Name: num, dtype: object
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-19
        • 1970-01-01
        相关资源
        最近更新 更多