基于前一日数值计算Python DataFrame指定列缺失值方案咨询
解决方案
你这个场景属于带断点的序列累积计算,pandas原生向量化函数很难直接适配(因为每次遇到预赋值的待计算值就要重置计算基准),下面给两种可直接用的实现方式:
1. 基础循环实现(适合小数据量,你当前一年365条数据优先选这个)
逻辑清晰容易调试,365条数据的循环耗时可以完全忽略,不用刻意追求向量化写法:
import pandas as pd # 第一步必须确保数据按日期升序排列,避免索引顺序混乱导致计算错误 df = df.sort_index() # 简化待计算列名方便后续调用 df = df.rename(columns={"value to calculate": "calc_val"}) # 初始化前序基准:取第一条的预赋值(也就是DOY1的默认值) prev_calc_val = df["calc_val"].iloc[0] prev_feature = df[["col1", "col2", "col3", "col4"]].iloc[0].values for idx in range(1, len(df)): current_row = df.iloc[idx] # 如果当前行已经有预计算值,直接重置基准,跳过计算 if pd.notna(current_row["calc_val"]): prev_calc_val = current_row["calc_val"] prev_feature = current_row[["col1", "col2", "col3", "col4"]].values continue # -------------------------- # 此处替换为你实际的计算公式 # 示例公式逻辑:当前值 = 前序计算值*权重 + 前一天特征与当天特征运算结果*权重 current_calc = prev_calc_val * 0.9 + (prev_feature[0] + current_row["col1"]) * 0.1 + (prev_feature[2] * current_row["col4"]) * 0.05 # -------------------------- # 把计算结果写入对应行 df.loc[df.index[idx], "calc_val"] = current_calc # 更新前序基准用于下一次计算 prev_calc_val = current_calc prev_feature = current_row[["col1", "col2", "col3", "col4"]].values
2. 高性能Numba实现(适合大数据量,比如数十年的日度数据)
如果后续你需要处理上万条以上的时间序列数据,可以用Numba编译循环逻辑,速度比纯Python循环快100倍以上:
import pandas as pd import numpy as np from numba import jit df = df.sort_index() df = df.rename(columns={"value to calculate": "calc_val"}) # 把需要计算的列转成numpy数组提高运算效率 calc_arr = df["calc_val"].values feature_arr = df[["col1", "col2", "col3", "col4"]].values # 用numba编译循环函数,nopython模式禁用Python解释器,性能最优 @jit(nopython=True) def calc_rolling_series(calc_arr, feature_arr): prev_calc = calc_arr[0] prev_feat = feature_arr[0] for i in range(1, len(calc_arr)): # 遇到预赋值直接重置基准 if not np.isnan(calc_arr[i]): prev_calc = calc_arr[i] prev_feat = feature_arr[i] continue # 替换为你实际的计算公式即可 current_calc = prev_calc * 0.9 + (prev_feat[0] + feature_arr[i][0]) * 0.1 + (prev_feat[2] * feature_arr[i][3]) * 0.05 calc_arr[i] = current_calc prev_calc = current_calc prev_feat = feature_arr[i] return calc_arr # 把计算结果写回原DataFrame df["calc_val"] = calc_rolling_series(calc_arr, feature_arr)
注意事项
- 如果你的数据包含多个年份,需要先按年份分组,每组单独执行上述计算逻辑,避免跨年使用前一年最后一天的数据计算当年第一天的数值
- 两种方案都已经自动适配「遇到预赋值就重置计算基准」的需求,不用额外加判断逻辑
内容的提问来源于stack exchange,提问作者Francesco_Palazzi
相关产品推荐
相关产品推荐

