如何高效对Pandas批量应用scipy.minimize求解带约束优化问题
高效批量求解带约束优化问题方案
针对10万行Pandas DataFrame的批量优化需求,结合你的目标函数与约束条件,可从以下几个方向实现高效处理:
1. 优先推导解析解(最快方案)
你的目标函数是凸函数(默认a>0,否则需额外判断),先求无约束最优解,再验证是否满足约束,能避免大量迭代计算:
- 无约束最优解推导:令梯度为0,解得
x₀*=b,x₁*=b² - 验证约束条件:
0 ≤ b + a*b² ≤ 10 ≤ a*b - b² ≤ b0 ≤ b ≤ 10 ≤ b² ≤ b
- 处理逻辑:
- 对DataFrame中满足所有约束的行,直接赋值
x₀*=b、x₁*=b² - 仅对不满足约束的行,再调用优化器求解边界最优解
- 对DataFrame中满足所有约束的行,直接赋值
2. 并行化处理非解析可行行
若部分行无法用解析解覆盖,利用每行求解独立的特性,用多进程并行处理:
示例代码
from multiprocessing import Pool import pandas as pd from scipy.optimize import minimize def solve_single(a, b): # 目标函数(复用你已实现的f、f_der、f_hess) def f(x): return a*(x[1]-x[0]**2)**2 + (b - x[0])**2 def f_der(x): # 你已实现的梯度函数 dx0 = -4*a*x[0]*(x[1]-x[0]**2) + 2*(x[0]-b) dx1 = 2*a*(x[1]-x[0]**2) return [dx0, dx1] def f_hess(x): # 你已实现的海森矩阵函数 h00 = -4*a*(x[1]-x[0]**2) + 8*a*x[0]**2 + 2 h01 = -4*a*x[0] h10 = -4*a*x[0] h11 = 2*a return [[h00, h01], [h10, h11]] # 定义约束 constraints = [ {'type': 'ineq', 'fun': lambda x: x[0] + a*x[1]}, {'type': 'ineq', 'fun': lambda x: 1 - (x[0] + a*x[1])}, {'type': 'ineq', 'fun': lambda x: a*x[0] - x[1]}, {'type': 'ineq', 'fun': lambda x: b - (a*x[0] - x[1])}, {'type': 'ineq', 'fun': lambda x: x[0]}, {'type': 'ineq', 'fun': lambda x: 1 - x[0]}, {'type': 'ineq', 'fun': lambda x: x[1]}, {'type': 'ineq', 'fun': lambda x: b - x[1]} ] # 用无约束解做初始点,加速收敛 x0 = [b, b**2] res = minimize(f, x0, jac=f_der, hess=f_hess, constraints=constraints, method='trust-constr') return res.x[0], res.x[1] # 并行处理主逻辑 if __name__ == '__main__': # 读取你的DataFrame df = pd.read_csv('your_data.csv') # 拆分解析可行与不可行的行 df['x0_unconstrained'] = df['b'] df['x1_unconstrained'] = df['b']**2 cond1 = (df['x0_unconstrained'] + df['a']*df['x1_unconstrained'] >= 0) & (df['x0_unconstrained'] + df['a']*df['x1_unconstrained'] <= 1) cond2 = (df['a']*df['x0_unconstrained'] - df['x1_unconstrained'] >= 0) & (df['a']*df['x0_unconstrained'] - df['x1_unconstrained'] <= df['b']) cond3 = (df['x0_unconstrained'] >= 0) & (df['x0_unconstrained'] <= 1) cond4 = (df['x1_unconstrained'] >= 0) & (df['x1_unconstrained'] <= df['b']) feasible_mask = cond1 & cond2 & cond3 & cond4 df.loc[feasible_mask, ['x0_star', 'x1_star']] = df.loc[feasible_mask, ['b', 'x1_unconstrained']].values # 并行处理不可行的行 infeasible_df = df[~feasible_mask].copy() params = list(zip(infeasible_df['a'], infeasible_df['b'])) with Pool(processes=4) as pool: # 根据CPU核心数调整进程数 results = pool.starmap(solve_single, params) infeasible_df[['x0_star', 'x1_star']] = results df = pd.concat([df[feasible_mask], infeasible_df]).sort_index()
3. 求解器参数调优
- 选择
trust-constr方法:该方法支持利用海森矩阵,比SLSQP收敛更快 - 调大收敛阈值:若对精度要求不高,可设置
tol=1e-5或1e-4,减少迭代次数 - 固定初始点:用无约束解作为初始点,避免随机初始点带来的额外迭代
内容的提问来源于stack exchange,提问作者Ishigami
相关产品推荐
相关产品推荐

