如何用Pandas计算每月15日至次月15日的均值(或n日至n日)
解决Pandas跨月周期(每月n日到次月n日)均值统计问题
核心思路
不用固定天数偏移(因各月天数不同会出错),而是通过判断日期的日部分给每条数据分配所属周期的起始标识,再按该标识分组计算均值。比如对于n=15:
- 日期≥当月15日:归属于「当月15日-次月15日」周期
- 日期<当月15日:归属于「上月15日-当月15日」周期
具体实现代码
import pandas as pd # 1. 示例数据(替换为你的DataFrame) df = pd.DataFrame({ 'timestamp': pd.date_range(start='2023-01-01', end='2023-03-31', freq='D'), 'value': range(90) }) # 2. 定义周期分割日(可修改为任意n,比如5、20) n = 15 # 3. 创建周期起始标识列 # 判断每条数据是否属于当月n日及之后的周期 mask = df['timestamp'].dt.day >= n # 生成周期起始日期:满足mask的用当月n日,不满足的用上月n日 df['period_start'] = pd.to_datetime( # 拼接年-月-n日字符串,处理月份补0 df['timestamp'].dt.year.astype(str) + '-' + df['timestamp'].dt.month.where(mask, df['timestamp'].dt.month - 1).astype(str).str.zfill(2) + '-' + str(n).zfill(2), errors='coerce' # 处理当月无n日的情况(如2月30日) ) # 对转换失败的日期(如2月30日),替换为对应月份的最后一天 df['period_start'] = df['period_start'].fillna( df['timestamp'].dt.to_period('M').apply(lambda x: x.start_time + pd.offsets.MonthEnd(0)) ) # 4. 按周期分组计算均值 result = df.groupby('period_start')['value'].mean().reset_index() # 重命名列(按需调整) result.columns = ['周期起始日期', 'value均值'] print(result)
示例输出
周期起始日期 value均值 0 2023-01-15 29.0 1 2023-02-15 58.5 2 2023-03-15 81.0
关键说明
- 避免固定天数偏移:比如直接给
timestamp加pd.DateOffset(days=15)会导致周期长度随月份天数波动,无法精准对齐「每月n日」的分割点。 - 兼容特殊月份:自动处理2月无30/31日、4/6/9/11月无31日的情况,转换失败时自动用当月最后一天作为周期起始。
- 灵活调整n:只需修改
n的值,即可适配任意「每月n日到次月n日」的统计需求。
内容的提问来源于stack exchange,提问作者joshua registe
相关产品推荐
相关产品推荐

