
本文介绍如何使用 Pandas 为分组数据动态添加多行,每行日期按组内指定的次数和天数间隔递增,核心依赖 pd.date_range、apply 和 explode 实现高效、可扩展的行扩展操作。
本文介绍如何使用 pandas 为分组数据动态添加多行,每行日期按组内指定的次数和天数间隔递增,核心依赖 `pd.date_range`、`apply` 和 `explode` 实现高效、可扩展的行扩展操作。
在数据分析中,常需基于原始分组记录(如 ID、起始日期、重复次数、时间步长)生成时间序列扩展行。例如,每个 ID 对应一个起始日期、需生成的行数 n_times 及每日/每若干日递增的 interval_days,目标是将单行扩展为多行,且每行日期严格按组内规则递推。
实现的关键在于:避免显式循环,利用向量化函数 + 列表展开。具体步骤如下:
- 定义日期生成函数:封装 pd.date_range,支持自定义年份(防止缺失年份导致解析失败)、起始日期(MM-dd 格式)、周期数与频率;
- 按行应用生成逻辑:使用 apply 将每组参数(n_times, interval_days, date (MM-dd))传入函数,返回 DatetimeIndex;
- 展开列表列:explode() 将每个单元格中的日期序列展开为多行;
- 格式化输出:用 .dt.strftime('%m-%d') 统一转为 MM-dd 字符串格式。
以下是完整可运行示例代码:
import pandas as pd
# 原始数据
df = pd.DataFrame({
'Id': [1, 2, 3, 4],
'n_times': [3, 1, 2, 4],
'interval_days': [4, 4, 5, 3],
'date (MM-dd)': ['03-01', '03-02', '03-05', '03-07']
})
def generate_date_range(n_times: int, interval_days: int, start_date: str, year: str = '2024'):
return pd.date_range(
start=f'{year}-{start_date}',
periods=n_times,
freq=f'{interval_days}D'
)
# 设置索引便于分组处理(Id 作为标识列保留)
result = df.set_index('Id')
result['date (MM-dd)'] = result.apply(
lambda x: generate_date_range(x['n_times'], x['interval_days'], x['date (MM-dd)']),
axis=1
)
result = result.explode('date (MM-dd)')
result['date (MM-dd)'] = result['date (MM-dd)'].dt.strftime('%m-%d')
# 重置索引并还原 Id 列
result = result.reset_index()
print(result)✅ 注意事项:
- 起始日期必须为 MM-dd 格式,函数内部自动补全年份(默认 '2024'),确保 pd.date_range 正确解析;若需适配不同年份,可将 year 列加入原始 DataFrame 并动态传入。
- freq=f'{interval_days}D' 表示固定日频(calendar days),如需工作日可改用 'B' 频率,但需同步调整 periods 逻辑。
- explode() 要求列中元素为 list 或 array-like;若某组 n_times=0,需提前过滤或处理空序列,否则会引发错误。
- 性能提示:该方案对数千组数据高效;若规模达百万级,建议改用 numpy.repeat + 向量化日期计算进一步优化。
通过此方法,你可在不破坏原始分组结构的前提下,精准、简洁地完成“每组按规则扩行”的典型时序建模预处理任务。


















