不同长度数组对应多条拟合曲线逐点取极值的Python代码求助
多组力-位移测试曲线拟合极值求解需求
问题描述
我在论文研究中开展了多组力随位移变化的测试,每组测试对应位移(X值)、力(Y值)两个数组。已通过pandas将数据导入Python,通过四阶多项式曲线拟合得到4条存在多处相交的拟合曲线,当前存在的问题是:四次拟合得到的x_line、y_line数组长度均不相同,需要得到覆盖所有x取值范围的两条新曲线,分别对应每个x坐标下所有拟合曲线的y值最大值、最小值,且需保留两条曲线的x、y值用于后续计算。
现有实现代码
import numpy as np from scipy.optimize import curve_fit import pandas as pd from matplotlib import pyplot as plt def objective_4(x,a,b,c,d,e): return a * x**4 +b*x**3 +c*x**2+d*x+e for i in range(8,12): pars, cov = curve_fit(objective_4, df.iloc[:,i][1:DATA_END_VALUES[i]],df.iloc[:,i+16][1:DATA_END_VALUES[i]]) x_line = np.arange(min(df.iloc[:,i][1:DATA_END_VALUES[i]]), max(df.iloc[:,i][1:DATA_END_VALUES[i]]), 1) a, b, c, d, e = pars y_line = objective_4(x_line, a, b, c, d, e) if i==8: y_line31=y_line x_line31=x_line if i==9: y_line32=y_line x_line32=x_line if i==10: y_line33=y_line x_line33=x_line if i==11: y_line34=y_line x_line34=x_line ymin3=np.empty(1182) plt.plot(x_line31,y_line31) plt.plot(x_line32,y_line32) plt.plot(x_line33,y_line33) plt.plot(x_line34,y_line34) plt.ylim(bottom=0) plt.show()
适配后可实现需求的代码
import numpy as np from scipy.optimize import curve_fit import pandas as pd from matplotlib import pyplot as plt def objective_4(x,a,b,c,d,e): return a * x**4 +b*x**3 +c*x**2+d*x+e # 存储所有拟合参数和x范围边界 fit_pars = [] all_x_min = [] all_x_max = [] for i in range(8,12): x_data = df.iloc[:,i][1:DATA_END_VALUES[i]] y_data = df.iloc[:,i+16][1:DATA_END_VALUES[i]] pars, cov = curve_fit(objective_4, x_data, y_data) fit_pars.append(pars) all_x_min.append(x_data.min()) all_x_max.append(x_data.max()) # 生成覆盖所有测试范围的统一x序列,步长保持原逻辑的1 global_x_min = np.min(all_x_min) global_x_max = np.max(all_x_max) x_uniform = np.arange(global_x_min, global_x_max, 1) # 计算所有曲线在统一x序列下的y值 all_y = [] for pars in fit_pars: y = objective_4(x_uniform, *pars) all_y.append(y) all_y = np.array(all_y) # 逐点计算最大、最小值得到上下包络 y_max = np.max(all_y, axis=0) y_min = np.min(all_y, axis=0) # 结果可视化验证 for idx,y in enumerate(all_y): plt.plot(x_uniform, y, alpha=0.5, label=f'拟合曲线{idx+1}') plt.plot(x_uniform, y_max, 'r--', linewidth=2, label='上包络(最大值)') plt.plot(x_uniform, y_min, 'b--', linewidth=2, label='下包络(最小值)') plt.ylim(bottom=0) plt.legend() plt.show() # 后续计算可直接调用x_uniform、y_max、y_min三个数组
代码逻辑说明
- 不再单独存储每条曲线的离散x/y采样点,改为存储四阶多项式的拟合参数,避免不同曲线采样范围不一致的问题
- 先统计所有测试组的x值上下限,生成覆盖全范围的统一步长x序列,步长和原逻辑保持一致为1
- 基于统一的x序列,用保存的拟合参数重新计算所有曲线的y值,保证所有曲线的y值和x序列一一对应
- 按行做最大/最小值计算,直接得到全范围的上下包络曲线
- 最终输出的
x_uniform为统一x坐标数组,y_max为对应每个x的最大值数组,y_min为对应每个x的最小值数组,可直接用于后续计算
内容的提问来源于stack exchange,提问作者Lodewijk Pleij
相关产品推荐
相关产品推荐

