如何高效实现Pandas日期对象间插值?生成人员可用月份表格
高效实现Pandas日期区间扩展(替代iterrows循环)
你的原代码用iterrows()逐行迭代+反复concat的方式,在数据量大时效率极低——因为iterrows()本身是逐行遍历的低效操作,而且每次concat都会创建新的DataFrame对象,带来大量内存开销和时间消耗。
下面是两种基于Pandas原生优化的高效实现方案,完全避免循环,性能提升显著:
方法1:用apply生成日期列表 + explode展开
这种方法代码简洁,兼顾可读性和效率,适合中等数据量场景:
import pandas as pd # 读取数据源(如果是Excel请替换为pd.read_excel) data = pd.read_csv('Dataset.csv') # 先将日期列转为datetime类型(确保后续日期运算正常) data['Start Date'] = pd.to_datetime(data['Start Date']) data['End Date'] = pd.to_datetime(data['End Date']) # 为每行生成对应的月末日期列表 data['Month'] = data.apply( lambda row: pd.date_range(start=row['Start Date'], end=row['End Date'], freq='M').tolist(), axis=1 ) # 将列表展开为独立行,并重命名列名匹配需求 final = data.explode('Month')[['Project', 'Month']].rename(columns={'Project': 'Name'})
方法2:全向量化操作(性能最优)
如果你的数据集非常大,推荐用这种完全无循环、无apply的方案,利用Pandas的向量化运算特性,效率达到最高:
import pandas as pd data = pd.read_csv('Dataset.csv') data['Start Date'] = pd.to_datetime(data['Start Date']) data['End Date'] = pd.to_datetime(data['End Date']) # 计算每个项目覆盖的月份总数 data['month_count'] = ( (data['End Date'].dt.year - data['Start Date'].dt.year) * 12 + data['End Date'].dt.month - data['Start Date'].dt.month + 1 # 包含起始月的计数 ) # 按月份数重复每行数据 expanded_data = data.loc[data.index.repeat(data['month_count'])] # 为每行计算对应的月末日期 expanded_data['Month'] = ( expanded_data['Start Date'] + pd.DateOffset(months=expanded_data.groupby(level=0).cumcount()) ).dt.to_period('M').dt.to_timestamp('M') # 整理输出格式 final = expanded_data[['Project', 'Month']].rename(columns={'Project': 'Name'}).reset_index(drop=True)
关键优化点:
- 避免了
iterrows()的逐行遍历,改用Pandas内部优化的向量化/批量操作 - 去掉了反复
concat的开销,改用explode或repeat一次性扩展数据 - 日期运算全部通过Pandas内置的日期偏移、时间序列方法完成,比手动循环生成更高效
内容的提问来源于stack exchange,提问作者Simon Joubert
相关产品推荐
相关产品推荐

