Pandas按周分组而不超过一个月
我想在我的pandas数据框中按周进行分组,但不想跨越一个月。比如说:
Date Value
0 2021-01-15 4
1 2021-01-17 3
2 2021-01-19 10
3 2021-02-04 1
按周分组的结果应该像这样:
Week Sum_value
0 2021-01-01-2021-01-06 0
...
3 2021-01-29-2021-01-31 5
所以一周的时间不应该跨越两个月。
2 个回答
2
一个可能的解决方案可以是这样的:
import pandas as pd
import numpy as np
df = pd.DataFrame({'Date': ['2021-01-15',
'2021-01-17','2021-01-19', '2021-02-04'],'Value': [4,3,10,1]})
df['Date'] = pd.to_datetime(df['Date'])
df['Week'] = df['Date'].dt.to_period('W').apply(lambda r: f'{r.start_time.date()}-{r.end_time.date()}')
df_grouped = df.groupby('Week').sum()
print(df_grouped)
输出结果如下:
Week Value
2021-01-11-2021-01-17 7
2021-01-18-2021-01-24 10
2021-02-01-2021-02-07 1
1
示例
我们需要一个简单且能重复的例子来回答问题。让我们来做一个吧。
import pandas as pd
import numpy as np
np.random.seed(0)
date = pd.date_range('2024-01-01', '2024-02-02')
df = pd.DataFrame({'Date': date,
'Value': np.random.randint(0, 10, len(date))})
数据框
Date Value
0 2024-01-01 5
1 2024-01-02 0
2 2024-01-03 3
... ... ...
30 2024-01-31 2
31 2024-02-01 3 <--next month
32 2024-02-02 8 <--next month
33 rows × 2 columns
代码
# if your Date column is not datetime type, convert to datetime
df['Date'] = pd.to_datetime(df['Date'])
# make grouper by week and month
grp1 = df['Date'].dt.to_period('M')
grp2 = df['Date'].dt.to_period('W')
# get you desired output
out = (df.groupby([grp1, grp2])
.agg(Week=('Date', 'first'),
last=('Date', 'last'),
Value_sum=('Value', 'sum'))
.reset_index(drop=True)
.assign(Week=lambda x: x['Week'].dt.strftime('%Y-%m-%d')
+ '-' + x.pop('last').dt.strftime('%Y-%m-%d'))
)
输出
Week Value_sum
0 2024-01-01-2024-01-07 30
1 2024-01-08-2024-01-14 40
2 2024-01-15-2024-01-21 35
3 2024-01-22-2024-01-28 36
4 2024-01-29-2024-01-31 7
5 2024-02-01-2024-02-02 11
为了把每个月的前7天都视为第一周,不管那几天是星期几,可以这样设置组:
grp1 = df['Date'].dt.to_period('M')
grp2 = df['Date'].dt.day.sub(1).floordiv(7)