求实现带重复项移除的Pandas DataFrame逆透视代码
Pandas 实现日期区间展开为连续日期记录
问题描述
现有如下结构的Pandas DataFrame:
| Material | End Date | Start Date | Qty |
|---|---|---|---|
| A | 10-Dec | 10-Dec | 4 |
| B | 13-Dec | 14-Dec | 2 |
| C | 14-Dec | 16-Dec | 3 |
| D | 15-Dec | 15-Dec | 0 |
| E | 16-Dec | 17-Dec | 1 |
需要将其处理为:把起止日期展开为连续的Date列,当Start Date和End Date相同时只保留一条记录,最终得到如下结果:
| Material | Date | Qty |
|---|---|---|
| A | 10-Dec | 4 |
| B | 13-Dec | 2 |
| B | 14-Dec | 2 |
| C | 14-Dec | 3 |
| C | 15-Dec | 3 |
| C | 16-Dec | 3 |
| D | 15-Dec | 0 |
| E | 16-Dec | 1 |
| E | 17-Dec | 1 |
实现代码
import pandas as pd # 构造原始DataFrame df = pd.DataFrame({ 'Material': ['A', 'B', 'C', 'D', 'E'], 'End Date': ['10-Dec', '13-Dec', '14-Dec', '15-Dec', '16-Dec'], 'Start Date': ['10-Dec', '14-Dec', '16-Dec', '15-Dec', '17-Dec'], 'Qty': [4, 2, 3, 0, 1] }) # 转换日期列为datetime类型,方便生成连续日期 df['Start Date'] = pd.to_datetime(df['Start Date'], format='%d-%b') df['End Date'] = pd.to_datetime(df['End Date'], format='%d-%b') # 处理部分行End Date早于Start Date的情况,确保起始日期≤结束日期 df[['start', 'end']] = df[['Start Date', 'End Date']].apply(lambda x: sorted(x), axis=1, result_type='expand') # 生成每行的连续日期序列 df['Date'] = df.apply(lambda row: pd.date_range(row['start'], row['end'], freq='D'), axis=1) # 展开日期序列为单独行,同时清理冗余列 result_df = df.explode('Date').drop(columns=['Start Date', 'End Date', 'start', 'end']) # 将日期格式转回原始的日-月样式 result_df['Date'] = result_df['Date'].dt.strftime('%d-%b') # 重置索引 result_df = result_df.reset_index(drop=True) print(result_df)
代码说明
- 先将字符串格式的日期转为
datetime类型,是生成连续日期的前提; - 针对原数据中存在的结束日期早于起始日期的行(如B、E),通过排序修正日期区间的逻辑顺序;
- 利用
pd.date_range为每行生成包含所有连续日期的序列; - 使用
explode方法将日期序列拆分为独立行,实现日期的展开; - 最后将日期格式还原为原始样式,整理输出结构。
内容的提问来源于stack exchange,提问作者kanika
相关产品推荐
相关产品推荐

