【问题标题】:pandas - How to get 7 day sum for groups when some groups do not have entries on all dayspandas - 当某些组全天都没有条目时,如何获得组的 7 天总和
【发布时间】:2017-07-15 03:07:25
【问题描述】:

我有一些这样的数据:

date, group_name, value
-------------------
2017-07-01, A, 10
2017-07-05, A, 4
2017-07-05, B, 21

我想计算每组的滚动 7 天总和,但只有当那一天的值 > 0 时,每组的数据才有记录。

我希望输出看起来像:

日期、组名、值、7d_sum_of_value -------------------------------------- 2017-07-01, A, 10, 10 2017-07-05, A, 4, 14 2017-07-05, B, 21, 21

【问题讨论】:

  • 你如何定义每 7 天?例如,是从月初开始每 7 天,还是每 7 天都在特定周内的每 7 天?
  • 添加那些缺少的indexgroupbyrollingsum
  • @joceratops,我将 7 天定义为当天和前 6 天。
  • @Wen,你能举一个添加缺失索引的例子吗?我以高基数对多列进行分组,约 700 万个独特排列。谢谢!
  • df.groupby('group_name')['value'].apply(lambda x:pd.rolling_sum(x.resample("1d"), 7, min_periods=1)).reset_index() and merge with original df 你需要我写完作为答案吗?

标签: python pandas


【解决方案1】:

使用timedeltas:

import pandas as pd
from datetime import datetime, timedelta

testdata = pd.DataFrame({'date': ['2017-07-01', '2017-07-05', '2017-07-05'], 'group_name': ['A', 'A', 'B'], 'value': [10, 4, 21]})
testdata['7d_sum_of_value'] = 0

for index1, row1 in testdata.iterrows(): # Iterate over all rows in data
    rolling_sum = row1['value'] # Initialize rolling_sum
    group_data = testdata[testdata['group_name'] == row1['group_name']] # Choose subset of data that pertains to the appropriate group
    for index2, row2 in group_data.iterrows(): 
        date_diff = datetime.strptime(row1['date'], '%Y-%m-%d')-datetime.strptime(row2['date'], '%Y-%m-%d') # Get time difference between two dates
        if (date_diff >= timedelta(0)) and (date_diff <= timedelta(7)) and (index1 != index2):
            rolling_sum += row2['value'] # Update rolling sum
    testdata.set_value(index1, '7d_sum_of_value', rolling_sum) # Insert rolling sum into data

【讨论】:

    【解决方案2】:

    你可以试试这个,但是根据你data的规模(700万),肯定有比我的效率更高的解决方案。

    df = pd.DataFrame({'date': ['2017-07-01', '2017-07-05', '2017-07-05'], 'group_name': ['A', 'A', 'B'], 'value': [10, 4, 21]})
    df.date=pd.to_datetime(df.date)
    df = df.set_index('date')
    df['date']=df.index
    
    A=df.groupby('group_name')['value'].apply(lambda x:pd.rolling_sum(x.resample("1d"), 7, min_periods=1)).reset_index()
    
    df.merge(A,left_on=['date','group_name'],right_on=['date','group_name'],how='left')
    
    
    
    Out[201]: 
      group_name  value_x       date  value_y
    0          A       10 2017-07-01     10.0
    1          A        4 2017-07-05     14.0
    2          B       21 2017-07-05     21.0
    

    【讨论】:

      猜你喜欢
      • 2018-02-18
      • 1970-01-01
      • 1970-01-01
      • 2019-07-20
      • 2023-04-02
      • 1970-01-01
      • 2017-03-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多