pandas 如何计算每个组ID的最近两周总和

mqxuamgl  于 2022-12-16  发布在  其他
关注(0)|答案(3)|浏览(108)

我有输入数据框

| 识别号|日期|金额|
| - ------|- ------|- ------|
| A类|2021年8月3日|一百|
| A类|2021年8月4日|一百|
| A类|2021年8月6日|二十个|
| A类|2021年8月7日|一百|
| A类|2021年8月9日|三百|
| A类|2021年8月11日|一百|
| A类|二○二一年八月十二日|一百|
| A类|二○二一年八月十三日|十个|
| A类|二○二一年八月二十三日|十个|
| A类|二○二一年八月二十四日|十个|
| A类|二〇二一年八月二十六日|十个|
| A类|二○二一年八月二十八日|十个|
所需输出 Dataframe
| 识别号|日期|金额|两周总和|
| - ------|- ------|- ------|- ------|
| A类|2021年8月3日|一百|三百二十|
| A类|2021年8月4日|一百|三百二十|
| A类|2021年8月6日|二十个|三百二十|
| A类|2021年8月7日|一百|三百二十|
| A类|2021年8月9日|三百|八三○|
| A类|2021年8月11日|一百|八三○|
| A类|二○二一年八月十二日|一百|八三○|
| A类|二○二一年八月十三日|十个|八三○|
| A类|二○二一年八月二十三日|十个|四十|
| A类|二○二一年八月二十四日|十个|四十|
| A类|二〇二一年八月二十六日|十个|四十|
| A类|二○二一年八月二十八日|十个|四十|
我想计算过去两周的总和,如twoweekSum=当前周的总和+前一周的总和,即当前周为34,则twoweekSum为34周的总和+ 33周的总和。
请帮助我在得到这个像输出 Dataframe ,这样我就可以用它作进一步的分析。谢谢大家!

eoigrqb6

eoigrqb61#

用途:

#convert values to datetimes
df['Date'] = pd.to_datetime(df['Date'])

#convert values to weeks
df['week'] = df['Date'].dt.isocalendar().week

#aggregate sum per ID and weeks, then add missing weeks and sum in rolling
f = lambda x: x.reindex(range(x.index.min(), x.index.max() + 1))
                .rolling(2, min_periods=1).sum()
df1 = df.groupby(['ID', 'week'])['Amount'].sum().reset_index(level=0).groupby('ID').apply(f)

print (df1)
         Amount
ID week        
A  31     320.0
   32     830.0
   33     510.0
   34      40.0

#last add to original DataFrame per ID and weeks
df=df.join(df1.rename(columns={'Amount':'TwoWeekSum'}),on=['ID','week']).drop('week',axis=1)
print (df)
   ID       Date  Amount  TwoWeekSum
0   A 2021-08-03     100       320.0
1   A 2021-08-04     100       320.0
2   A 2021-08-06      20       320.0
3   A 2021-08-07     100       320.0
4   A 2021-08-09     300       830.0
5   A 2021-08-11     100       830.0
6   A 2021-08-12     100       830.0
7   A 2021-08-13      10       830.0
8   A 2021-08-23      10        40.0
9   A 2021-08-24      10        40.0
10  A 2021-08-26      10        40.0
11  A 2021-08-28      10        40.0
erhoui1w

erhoui1w2#

尝试使用groupbydt.week对 Dataframe 进行分组,然后使用transformsum每周将这些值相加并重复这些值:

df['TwoWeekSum'] = df.groupby(df['Date'].dt.week)['Amount'].transform('sum')

然后:

print(df)

给出:

ID        Date  Amount  TwoWeekSum
0   A  2021-08-03     100         320
1   A  2021-08-04     100         320
2   A  2021-08-06      20         320
3   A  2021-08-07     100         320
4   A  2021-08-09     300         830
5   A  2021-08-11     100         830
6   A  2021-08-12     100         830
7   A  2021-08-13      10         830
8   A  2021-08-23      10          40
9   A  2021-08-24      10          40
10  A  2021-08-26      10          40
11  A  2021-08-28      10          40
6g8kf2rb

6g8kf2rb3#

per = pd.period_range(df['Date'].min(), df['Date'].max(), freq='w')
mapper = df.groupby(df['Date'].astype('Period[W]')).sum().reindex(per, fill_value=0).rolling(2, 1).sum()['Amount']
out = df['Date'].astype('Period[W]').map(mapper)

out

0     320.0
1     320.0
2     320.0
3     320.0
4     830.0
5     830.0
6     830.0
7     830.0
8      40.0
9      40.0
10     40.0
11     40.0
Name: Date, dtype: float64

out设置为两周总和列

df.assign(TwoWeekSum=out)

    ID  Date     Amount TwoWeekSum
0   A   2021-08-03  100 320.0
1   A   2021-08-04  100 320.0
2   A   2021-08-06  20  320.0
3   A   2021-08-07  100 320.0
4   A   2021-08-09  300 830.0
5   A   2021-08-11  100 830.0
6   A   2021-08-12  100 830.0
7   A   2021-08-13  10  830.0
8   A   2021-08-23  10  40.0
9   A   2021-08-24  10  40.0
10  A   2021-08-26  10  40.0
11  A   2021-08-28  10  40.0

更新

如果每个ID、groupby和merge

per = pd.period_range(df['Date'].min(), df['Date'].max(), freq='w')
s = df['Date'].astype('Period[W]')
idx = pd.MultiIndex.from_product([df['ID'].unique(), per])
df1 = df.groupby(['ID', s]).sum().reindex(idx, fill_value=0).rolling(2, 1).agg(sum).reset_index().set_axis(['ID', 'period', 'TwoWeekSum'], axis=1)
df.assign(period=s).merge(df1, how='left').drop('period', axis=1)

相关问题