You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas DataFrame中按距每月首次出现偏移行分组?

实现Pandas分组边界的行偏移

场景1:对每个年月组进行内部行偏移(保留原分组结构)

这种方式是在原始的年月分组基础上,每个组跳过前N行(正偏移)或后N行(负偏移),保留调整后的组用于后续处理。

步骤代码

  1. 确保日期列是datetime类型:
import pandas as pd

# 假设日期列名为date
df['date'] = pd.to_datetime(df['date'])
  1. 添加分组标签和组内行序号:
# 生成年月分组标签
df['year_month'] = df['date'].dt.to_period('M')
# 计算每个组内的行序号(从0开始计数)
df['group_row_idx'] = df.groupby('year_month').cumcount()
# 计算每个组的总行数
group_sizes = df.groupby('year_month').size().rename('group_size')
df = df.merge(group_sizes, left_on='year_month', right_index=True)
  1. 根据偏移量筛选行:
# 设置偏移量,正偏移表示跳过每组前N行,负偏移表示跳过每组后N行
offset = 1  # 可替换为-3等其他值

if offset > 0:
    # 正偏移:保留组内行序号 >= offset的行
    filtered_df = df[df['group_row_idx'] >= offset]
elif offset < 0:
    # 负偏移:保留组内行序号 <= (组内总行数-1 - 绝对值偏移量)的行
    abs_offset = abs(offset)
    filtered_df = df[df['group_row_idx'] <= (df['group_size'] - 1 - abs_offset)]
else:
    # 偏移量为0,保留所有行
    filtered_df = df.copy()
  1. 对筛选后的结果进行分组处理:
# 按年月分组做后续聚合操作,比如求和、均值
result = filtered_df.groupby('year_month', as_index=False).agg({'value': 'sum'})

场景2:跨月的偏移分组(调整分组边界为指定行)

如果需要将分组边界设置为每个月的第N行日期,形成跨月的连续分组(比如从1月第2行到2月第2行作为一个组),可以用以下方法:

步骤代码

  1. 预处理日期列:
df['date'] = pd.to_datetime(df['date'])
offset = 1  # 偏移量,正为取每组第N行,负为取每组倒数第N行
  1. 获取每个月的边界日期:
if offset > 0:
    # 取每个年月组的第offset行(0开始计数)作为边界
    boundary_dates = df.groupby(df['date'].dt.to_period('M')).nth(offset)['date']
elif offset < 0:
    # 取每个年月组的倒数第abs(offset)行作为边界
    abs_offset = abs(offset)
    boundary_dates = df.groupby(df['date'].dt.to_period('M')).nth(-abs_offset)['date']
else:
    # 偏移量为0,取每月首日作为边界
    boundary_dates = df.groupby(df['date'].dt.to_period('M')).nth(0)['date']

# 排序边界日期,并补充首尾边界确保覆盖所有数据
boundary_dates = boundary_dates.sort_values()
boundary_dates = pd.concat([
    pd.Series([df['date'].min() - pd.Timedelta(days=1)]),
    boundary_dates,
    pd.Series([df['date'].max() + pd.Timedelta(days=1)])
])
  1. 生成偏移后的分组标签:
# 用cut将日期分配到对应的区间,right=False表示左闭右开区间
df['offset_group'] = pd.cut(
    df['date'],
    bins=boundary_dates,
    labels=boundary_dates[1:-1],
    right=False
)
  1. 按新分组进行后续处理:
# 按偏移后的分组做聚合操作
result = df.groupby('offset_group', as_index=False).agg({'value': 'mean'})

验证示例

  • 对于日期序列1/1,1/2,...,2/1,2/2,2/3,偏移量1时,offset_group为1/2的组包含1/2到2/1的所有行;若需要包含2/2,可将right=True,并调整边界日期为下一个月的边界日期。

内容的提问来源于stack exchange,提问作者John Glen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 11:05:28