如何基于期望输出调整Arps方程参数di?Python实现方法
Python实现递减曲线分析中Arps方程递减率的自动调整
问题说明
需要调整Arps方程的递减率di,使原始数据与预测数据的总和匹配参考值sum_reference=15。现有原始数据、初始参数及当前计算结果如下:
原始数据
import pandas as pd import numpy as np df = pd.DataFrame({"YEAR":[2019, 2020, 2021, 2022, 2023],"DATA":[0.5, 1, 2, 3, 4]})
初始参数与当前计算
sum_reference = 15 # 目标总和 n_periods = 3 # 预测年数 qi = 4 # 最后一个原始数据值 di_initial = 0.5 # 初始递减率 # 生成预测数据 eq = qi / (1 + di_initial * np.arange(1, n_periods + 1)) eq_df = pd.DataFrame({"YEAR":np.nan,"DATA":eq},index=np.arange(1, n_periods + 1)) df_combined = pd.concat([df, eq_df]) # 当前总和与差值 current_sum = df_combined["DATA"].sum() print(f"当前总和: {current_sum:.3f},与参考值差值: {sum_reference - current_sum:.3f}") # 输出:当前总和: 13.233,与参考值差值: 1.767
当前总和与参考值存在差值,需要自动调整di让差值为0。
实现方法
利用scipy.optimize模块的求解函数,构造误差方程并找到根(即误差为0时的di值),实现类似Excel单变量求解的功能。
完整代码
import pandas as pd import numpy as np from scipy.optimize import root # 1. 计算原始数据的固定总和 original_sum = df["DATA"].sum() # 2. 定义误差函数:输入di,返回总和与参考值的差值 def error_function(di): # 生成预测数据 pred_data = qi / (1 + di * np.arange(1, n_periods + 1)) pred_sum = pred_data.sum() # 返回差值(目标总和 - 原始总和 - 预测总和) return sum_reference - original_sum - pred_sum # 3. 求解误差为0时的di result = root(error_function, x0=di_initial) if result.success: optimal_di = result.x[0] print(f"最优递减率di: {optimal_di:.4f}") # 验证结果 pred_data_opt = qi / (1 + optimal_di * np.arange(1, n_periods + 1)) total_sum = original_sum + pred_data_opt.sum() print(f"调整后的总总和: {total_sum:.4f},与参考值差值: {sum_reference - total_sum:.4f}") # 生成最终合并数据(补全预测年份) eq_df_opt = pd.DataFrame({"YEAR":[2024,2025,2026],"DATA":pred_data_opt}) df_final = pd.concat([df, eq_df_opt], ignore_index=True) print("\n最终数据:") print(df_final) else: print("求解失败,原因:", result.message)
代码说明
original_sum:提前计算原始数据的固定总和,避免重复运算error_function:核心逻辑,输入di后计算预测数据总和,返回目标总和与实际总和的差值,我们需要找到让该差值为0的diroot函数:从初始值di_initial开始迭代,找到误差函数的根,即满足条件的最优di
运行结果示例
最优递减率di: 0.3036 调整后的总总和: 15.0000,与参考值差值: 0.0000 最终数据: YEAR DATA 0 2019 0.500000 1 2020 1.000000 2 2021 2.000000 3 2022 3.000000 4 2023 4.000000 5 2024 3.067485 6 2025 2.533058 7 2026 2.199457
内容的提问来源于stack exchange,提问作者user026
相关产品推荐
相关产品推荐

