【问题标题】:Sum of true values over past n dates in pandas大熊猫过去 n 个日期的真实值总和
【发布时间】:2020-03-26 04:15:40
【问题描述】:

我有几千行的数据框,其中包含地理、response_dates 和 True/False for in_compliance 列。

df = pd.DataFrame( { 
"geography" : ["Baltimore", "Frederick", "Annapolis", "Hagerstown", "Rockville" , "Salisbury","Towson","Bowie"] , 
"response_date" : ["2018-03-31", "2018-03-30", "2018-03-28", "2018-03-28", "2018-04-02", "2018-03-30","2018-04-07","2018-04-02"],
"in_compliance" : [True, True, False, True, False, True, False, True]})

我想在 response_date 列中添加一列,表示最近四个日期的 True 值的数量,包括该行的 response_date。所需输出的示例:

 geography  response_date   in_compliance   Past_4_dates_sum_of_true
Baltimore   2018-03-24  True    1
Baltimore   2018-03-25  False   1
Baltimore   2018-03-26  False   1
Baltimore   2018-03-27  False   1
Baltimore   2018-03-30  False   0
Baltimore   2018-03-31  True    1
Baltimore   2018-04-01  True    2
Baltimore   2018-04-02  True    3
Baltimore   2018-04-03  False   3
Baltimore   2018-04-06  True    3
Baltimore   2018-04-07  True    3
Baltimore   2018-04-08  False   2

我尝试了不同的 groupby 和 rolling 方法。但我得到的结果不是我期望和需要的。

df.groupby('city').resample('d').sum().fillna(0).groupby('city').rolling(4,min_periods=1).sum()

这是我采取的另一种方法:

    df1 = df.groupby(['city']).apply(lambda x: x.set_index('response_date').resample('1D').first())
    df2 = df1.groupby(level=0)['in_compliance']\
         .apply(lambda x: x.shift().rolling(min_periods=1,window=4).count())\
         .reset_index(name='Past_4_dates_sum_of_true')

【问题讨论】:

    标签: python pandas boolean pandas-groupby rolling-computation


    【解决方案1】:

    我认为您可以将rolling4days 与4d 一起使用:

    df = df.sort_values(['city','response_date'])
    df = df.set_index('response_date')
    
    df['new'] = (df.groupby('city')['in_compliance']
                   .rolling('4d',min_periods=1)
                   .sum()
                   .astype(int)
                   .reset_index(level=0, drop=True))
    df = df.reset_index()
    print (df)
       response_date       city  in_compliance  Past_4_dates_sum_of_true  new
    0     2018-03-24  Baltimore           True                         1    1
    1     2018-03-25  Baltimore          False                         1    1
    2     2018-03-26  Baltimore          False                         1    1
    3     2018-03-27  Baltimore          False                         1    1
    4     2018-03-30  Baltimore          False                         0    0
    5     2018-03-31  Baltimore           True                         1    1
    6     2018-04-01  Baltimore           True                         2    2
    7     2018-04-02  Baltimore           True                         3    3
    8     2018-04-03  Baltimore          False                         3    3
    9     2018-04-06  Baltimore           True                         3    1 <-difference because 2018-04-05 missing
    10    2018-04-07  Baltimore           True                         3    2
    11    2018-04-08  Baltimore          False                         2    2
    

    【讨论】:

    • 谢谢 - 这对于没有 response_date 间隔的响应日期序列非常有效。感谢您注意到由差距引起的差异。有没有办法让滚动 4d 倒数 df 中的四个 日期,而不是四个
    • @JamesMiller - 你觉得像你的最后一段吗?我发现只会将您的解决方案 df1 = df.groupby(['city']).apply(lambda x: x.set_index('response_date').resample('1D').first()) 简化为 df1 = df.groupby(['city']).resample('1D').first()(在创建 DatetimeIndex 之前)
    • 创建 DatetimeIndex 的最佳方法是什么?我已经尝试了几种方法,并得到 response_date 是“Int64Index”实例的错误。
    • @JamesMiller 使用 df = df.set_index('response_date')
    • 谢谢@jezrael。我最终添加了一列从回复日期到审核开始之间的工作日数。然后,我稍微修改了您的代码以获取前四行的 in_compliance 总和,而不管日期之间的差距如何。此post 协助。
    【解决方案2】:

    更简单:

    df['Past_4_dates_sum_of_true'] = df.rolling(4, min_periods=1)['in_compliance'].sum().astype(int)
    

    输出:

           geography response_date  in_compliance  Past_4_dates_sum_of_true
    0   Baltimore    2018-03-24           True                         1
    1   Baltimore    2018-03-25          False                         1
    2   Baltimore    2018-03-26          False                         1
    3   Baltimore    2018-03-27          False                         1
    4   Baltimore    2018-03-30          False                         0
    5   Baltimore    2018-03-31           True                         1
    6   Baltimore    2018-04-01           True                         2
    7   Baltimore    2018-04-02           True                         3
    8   Baltimore    2018-04-03          False                         3
    9   Baltimore    2018-04-06           True                         3
    10  Baltimore    2018-04-07           True                         3
    11  Baltimore    2018-04-08          False                         2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-20
      • 1970-01-01
      • 1970-01-01
      • 2022-10-14
      • 2020-02-21
      • 1970-01-01
      相关资源
      最近更新 更多