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

Python/Pandas基于ID生成起止月区间内的新行并制作透视表

Pandas 按日期间隔展开行并生成月度透视表解决方案

步骤1:日期格式预处理

先把start_date和end_date列转换为pandas可识别的日期类型,方便后续生成连续月份序列:

import pandas as pd

# 示例数据构造,可直接替换为你的实际数据源
df = pd.DataFrame({
    'id': [477,518,553,925,948,971,987,117,117,133],
    'start_date': ['2020-02','2020-08','2020-03','2020-07','2020-05','2020-02','2020-01','2020-06','2020-05','2020-05'],
    'end_date': ['2020-04','2020-08','2020-04','2020-09','2020-06','2020-07','2020-02','2020-07','2020-07','2020-06']
})

# 转换为日期格式
df['start_date'] = pd.to_datetime(df['start_date'])
df['end_date'] = pd.to_datetime(df['end_date'])

步骤2:按月份范围展开为多行

为每行生成start_date到end_date之间的所有月份列表,再通过explode拆分为独立行:

# 生成每行覆盖的月份列表,输出为YYYY-MM格式
df['month_list'] = df.apply(
    lambda x: pd.date_range(start=x['start_date'], end=x['end_date'], freq='MS').strftime('%Y-%m').tolist(),
    axis=1
)

# 拆分为多行,仅保留需要的id和月份字段
df_expanded = df.explode('month_list')[['id', 'month_list']].rename(columns={'month_list': 'dates'})

此时df_expanded结构和你给出的示例完全一致,每个id对应范围内的所有月份都会生成独立行。

如果你同一个id存在重复的月份区间,且需要结果仅标记「是否存在」(最大值为1),可以新增一步去重:

df_expanded = df_expanded.drop_duplicates()

步骤3:生成透视表

直接用crosstab即可快速生成你需要的0-1透视表,写法比pivot_table更简洁:

pivot_result = pd.crosstab(
    index=df_expanded['id'],
    columns=df_expanded['dates'],
    dropna=False
).reindex(sorted(df_expanded['dates'].unique()), axis=1, fill_value=0)

如果要保留你原来的pivot_table写法,调整为如下即可得到完全一致的结果:

pivot_result = pd.pivot_table(
    df_expanded,
    index='id',
    columns='dates',
    aggfunc='size',
    fill_value=0
)

输出结果完全符合你的预期,单元格值为1代表对应id在该月份处于有效期内,0代表不在。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 13:45:01