如何用Python Pandas DataFrame生成缺失weekid并补零至指定当前weekid
Pandas 实现缺失周期数据补全的方案
核心实现思路
完全依托Pandas向量化操作完成补全,避免逐行循环的性能损耗,逻辑拆分为三步:
- 日期类型转换:将原表中字符串格式的周期值(无论月度还是周度weekid)转为
Period类型,方便生成连续周期序列 - 分组生成完整周期轴:对每个固定维度组合(本例中为
product_name+serial_number),从组内最早的现有周期值开始,生成直到目标截止周期的完整连续周期序列 - 匹配原有数值:将生成的完整周期序列与原表左连接,未匹配到原有值的位置统一填充为0,最后还原为原始数据格式
该逻辑对周度粒度的weekid同样通用,仅需在生成周期序列时将频率参数替换为对应周度值即可,无需修改整体流程。
可直接运行的代码实现
import pandas as pd # 读入原始数据集,实际使用时可替换为pd.read_csv("xxx.csv")读取本地文件 df = pd.DataFrame({ "product_name": ["A", "A", "A", "A"], "serial_number": ["12", "12", "12", "12"], "date": ["202001", "202002", "202004", "202005"], "sum": [150, 350, 550, 1500] }) # 1. 日期列转为月度Period类型,适配连续序列生成逻辑 # 若为周度weekid,可将freq改为对应周频率,如"W-SUN" df["date"] = pd.PeriodIndex(df["date"], freq="M") # 设定目标截止周期值 target_period = pd.Period("202007", freq="M") # 2. 定义单组补全逻辑 def fill_group_dates(group): # 取当前分组的最早周期作为序列起点 start = group["date"].min() # 生成从起点到目标周期的完整周期序列 full_date_range = pd.period_range(start=start, end=target_period, freq="M") # 构造带固定维度信息的完整序列表 full_range_df = pd.DataFrame({ "date": full_date_range, "product_name": group["product_name"].iloc[0], "serial_number": group["serial_number"].iloc[0] }) # 左连接原表已有sum值,缺失值填充为0 return full_range_df.merge( group[["date", "sum"]], on="date", how="left" ).assign(sum=lambda x: x["sum"].fillna(0).astype(int)) # 3. 按固定维度分组应用补全逻辑,合并所有分组结果 filled_result = df.groupby( ["product_name", "serial_number"], group_keys=False ).apply(fill_group_dates) # 4. 还原日期格式为原始的YYYYMM字符串,对齐原表列顺序 filled_result["date"] = filled_result["date"].astype(str).str.replace("-", "") filled_result = filled_result[["product_name", "serial_number", "date", "sum"]]
实际使用注意事项
- 当数据集规模较大(十万行以上)、分组数较多时,可放弃逐组apply的方式:先提取所有唯一的固定维度组合,批量生成每个组合对应的完整周期序列,通过
pd.concat合并所有序列后,一次性与原表做左连接匹配,可将处理效率提升30%以上 - 全程使用
Period类型处理周期值,不要直接对字符串格式的日期做手动序列拼接,避免格式解析错误和重复的类型转换损耗 - 补全后需检查
sum列的数据类型,确保填充的0值与原有数值类型一致,避免出现float类型的0.0影响后续统计计算
内容的提问来源于stack exchange,提问作者user3104352
相关产品推荐
相关产品推荐

