基于滞后偏移计算DataFrame列差值并生成error列的实现需求
解决方案:基于滞后量计算误差并重塑DataFrame
核心实现思路
通过将宽表转换为长表,统一处理列序号匹配,计算滞后量后关联对应实际值,最终生成目标格式的结果表。以下是针对48列场景的通用实现代码:
步骤1:导入依赖并构造示例数据
import pandas as pd import numpy as np # 构造示例基础数据框(实际场景可直接读取你的base_df) base_df = pd.DataFrame({ 'mname': [0], 'p_code': ['101_1210'], 'p_name': ['BankABC'], 'fcval': [5590890], 'shotdate': ['2015-02-05'], 'actual_1': [10], 'actual_2': [20], 'actual_3': [30] # 实际场景补充actual_4到actual_48 }) # 构造示例控制数据框(实际场景可直接读取你的control_df) control_df = pd.DataFrame({ 'mname': [30], 'p_code': ['101_1210'], 'p_name': ['BankABC'], 'fcval': [5590890], 'shotdate': ['2015-02-05'], 'prd_1': [15], 'prd_2': [30], 'prd_3': [40] # 实际场景补充prd_4到prd_48 })
步骤2:将宽表转换为长表,提取序号
# 处理基础数据框:拆分actual列并提取序号 base_long = base_df.melt( id_vars=['mname', 'p_code', 'p_name', 'fcval', 'shotdate'], var_name='actual_col', value_name='actual_value' ) base_long['mNumber'] = base_long['actual_col'].str.extract(r'(\d+)').astype(int) # 处理控制数据框:拆分prd列并提取序号 control_long = control_df.melt( id_vars=['mname', 'p_code', 'p_name', 'fcval', 'shotdate'], var_name='prd_col', value_name='prd_value' ) control_long['mNumber'] = control_long['prd_col'].str.extract(r'(\d+)').astype(int)
步骤3:计算滞后量并匹配对应实际值
# 计算滞后量offset = mname // 30 control_long['offset'] = control_long['mname'] // 30 # 计算需要匹配的actual序号:prd序号 + 滞后量 control_long['actual_mNumber'] = control_long['mNumber'] + control_long['offset'] # 关联基础数据框的实际值,确保业务主键匹配 merged_df = pd.merge( control_long, base_long[['p_code', 'p_name', 'fcval', 'shotdate', 'mNumber', 'actual_value']], left_on=['p_code', 'p_name', 'fcval', 'shotdate', 'actual_mNumber'], right_on=['p_code', 'p_name', 'fcval', 'shotdate', 'mNumber'], how='left', suffixes=('', '_base') )
步骤4:计算误差并整理为目标格式
# 计算误差:actual_value - prd_value,actual为NaN时error自动为NaN merged_df['error'] = merged_df['actual_value'] - merged_df['prd_value'] # 筛选目标列并排序 final_df = merged_df[['mname', 'p_code', 'p_name', 'fcval', 'shotdate', 'mNumber', 'error']] final_df = final_df.sort_values('mNumber').reset_index(drop=True)
最终结果展示
运行上述代码后,final_df将输出符合要求的格式:
mname p_code p_name fcval shotdate mNumber error 0 30 101_1210 BankABC 5590890 2015-02-05 1 5.0 1 30 101_1210 BankABC 5590890 2015-02-05 2 0.0 2 30 101_1210 BankABC 5590890 2015-02-05 3 NaN
适配48列场景说明
- 代码中
melt方法会自动识别所有以actual_和prd_开头的列,无需手动修改列名 - 关联逻辑通过业务主键(p_code、p_name、fcval、shotdate)确保跨表行匹配准确
- 当
actual_{N+offset}不存在时(如序号超出48),actual_value会被设为NaN,对应的error也自动为NaN,完全符合需求
内容的提问来源于stack exchange,提问作者Obiii
相关产品推荐
相关产品推荐

