基于日期差复制行并递增起始日期的Python技术问题
问题分析与解决方案
你的代码核心问题是只复制了原行数据,没有对起始日期做递增修改,所以复制出来的所有行起始日期都和原行一致。下面提供两种解决思路,从修改原有逻辑到更高效的pandas向量化方法:
方法一:修改原有循环逻辑
先确保日期列是可运算的datetime类型,然后在复制行时手动递增起始日期:
import pandas as pd # 先把起始日期转成datetime类型,否则没法做日期加法 Fortnight_1['start date'] = pd.to_datetime(Fortnight_1['start date']) # 遍历每一行 for s in range(len(Fortnight_1)): diff = Fortnight_1['Date_Difference'].iloc[s] if diff > 0: original_row = Fortnight_1.iloc[s].copy() # 循环生成diff次递增后的行(从1开始,避免重复原行) for i in range(1, int(diff) + 1): new_row = original_row.copy() # 起始日期加i天 new_row['start date'] = original_row['start date'] + pd.Timedelta(days=i) # 追加到df,注意加ignore_index避免索引混乱 df = df.append(new_row, ignore_index=True)
注意:pandas 2.0及以上版本已经弃用
append,更推荐用pd.concat([df, new_row.to_frame().T], ignore_index=True)替代。
方法二:高效向量化处理(推荐)
循环处理大数据集效率极低,用pandas的apply+explode可以一次性完成,速度快很多:
import pandas as pd # 第一步还是转日期类型 Fortnight_1['start date'] = pd.to_datetime(Fortnight_1['start date']) # 为每行生成从原起始日期到起始日期+日期差的连续日期序列 Fortnight_1['Dates'] = Fortnight_1.apply( lambda row: pd.date_range( start=row['start date'], end=row['start date'] + pd.Timedelta(days=row['Date_Difference']), freq='D' ), axis=1 ) # 把日期序列展开成多行,同时保留其他列数据 df_expanded = Fortnight_1.explode('Dates').reset_index(drop=True) # 替换原start date列(或者保留原列,根据需求调整) df_expanded['start date'] = df_expanded['Dates'] df_expanded = df_expanded.drop('Dates', axis=1)
关键注意点
- 必须先将
start date转换为datetime类型,否则无法进行日期递增运算 - 如果
Date_Difference的单位不是天(比如小时、周),把pd.Timedelta(days=i)改成对应单位即可(比如hours=i) - 若初始
df不包含原数据,需要先把Fortnight_1的所有行追加进去,再执行上述逻辑
内容的提问来源于stack exchange,提问作者vishal yadav
相关产品推荐
相关产品推荐

