
本文介绍如何将包含起止年份的宽表数据,高效转换为按年展开的长表格式,核心方法是利用 pandas 的 explode() 函数配合 range 生成逐年序列,兼具简洁性与高性能。
本文介绍如何将包含起止年份的宽表数据,高效转换为按年展开的长表格式,核心方法是利用 pandas 的 `explode()` 函数配合 `range` 生成逐年序列,兼具简洁性与高性能。
在处理面板数据或时间序列分析时,常需将“时间段”(如 from_year–to_year)展开为“时间点”(每年一行)。对于大规模数据,效率至关重要。pandas 自 0.25 版本起支持 explode() 方法,专为展开 list-like 列而设计,是当前最简洁、最高效的解决方案。
以下为完整实现步骤:
-
构造原始数据
import pandas as pd
df = pd.DataFrame({ 'from_year': [1990, 1987, 2000, 2010], 'to_year': [1993, 1992, 2000, 2011], 'id': [1, 2, 3, 4], 'gender': ['Female', 'Male', 'Male', 'Female'] })
2. **生成年份列表并爆炸展开**
关键一步:用列表推导式构建 `range(from_year, to_year + 1)`,同时用 `pop()` 原地移除旧列,避免冗余:
```python
df['year'] = [range(x, y + 1) for x, y in zip(df.pop('from_year'), df.pop('to_year'))]
df = df.explode('year').reset_index(drop=True)✅ 输出即为目标长表格式,id、gender 自动广播至每一行,year 严格按区间展开。
注意事项:
- range(x, y+1) 确保包含 to_year(闭区间);
- explode() 要求目标列为 list、tuple 或 array-like,range 对象完全兼容;
- 若数据量极大(百万级区间),可考虑 pd.concat([pd.Series(range(x, y+1)) for ...]) 配合 pd.concat(..., keys=...) 实现更底层优化,但绝大多数场景下 explode 已足够快且内存友好;
- 该方法天然支持空区间(如 from_year > to_year)——此时 range 为空,对应行将被自动丢弃,符合逻辑预期。
最终结果结构清晰、可直接用于 groupby('year')、时间聚合或绘图,是构建时间维度分析基础表的标准实践。

















