Pandas按周分组而不超过一个月

-1 投票
2 回答
57 浏览
提问于 2025-04-14 15:30

我想在我的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)

撰写回答