针对指数型数据的类UnivariateSpline插值实现方案咨询
问题根因
你遇到的插值偏差问题,核心是待插值的蒸气压数据跨了超过20个数量级,直接对原始数值做插值时,低数值区间的极小误差在对数坐标下会被放大到肉眼可见的偏离程度,这是UnivariateSpline直接作用于原始vp_in数据失效的根本原因。
解决方案
正确的处理逻辑是先对蒸气压取对数,在对数域完成插值后再还原为实际数值,具体实现可以参考如下修改后的代码:
import numpy as np from scipy.interpolate import interp1d import matplotlib.pyplot as plt temp_vp = np.array([280.0,290.0,300.0,310.0,320.0,330.0,340.0,350.0,360.0,370.0,380.0,390.0,400.0,410.0,420.0,430.0,440.0,450.0,460.0,470.0,480.0,490.0,500.0]) vp_in = np.array([3.88e-52,5.16e-50,4.95e-48,3.53e-46,1.93e-44,8.26e-43,2.83e-41,7.93e-40,1.85e-38,3.62e-37,6.07e-36,8.79e-35,1.11e-33,1.25e-32,1.24e-31,1.11e-30,9.03e-30,6.66e-29,4.51e-28,2.81e-27,1.62e-26,8.72e-26,4.38e-25]) # 对蒸气压取对数后做线性插值,外推区域使用边界值填充 log_vp = np.log(vp_in) vp_f_log = interp1d(temp_vp, log_vp, kind='linear', fill_value=(log_vp[0], log_vp[-1]), bounds_error=False) # 插值后还原为实际蒸气压 vp_f = lambda x: np.exp(vp_f_log(x)) tempspace = np.linspace(200,10000,10000) fig=plt.figure(figsize=(4.5,3.6)) ax=fig.add_subplot(1,1,1) ax.minorticks_on() ax.set_axisbelow(True) ax.grid(which='major', color='black', linestyle='-', zorder=1, linewidth=0.4, alpha = 0.12) ax.grid(which='minor', color='black', linestyle='-', zorder=1, linewidth=0.4, alpha = 0.12) ax.scatter(temp_vp,vp_in, color = 'black', label = 'data', s= 5, zorder = 3) ax.plot(tempspace, vp_f(tempspace), color = 'blue', label = 'Fit', zorder = 2) ax.set_yscale('log') ax.set_xscale('log') ax.set_xlabel('Temperature [K]') ax.set_ylabel('Vapor Pressure [Pa]') ax.legend(labelspacing=0.25, fontsize = 8) plt.xlim([250,600]) plt.savefig('Al_vpdata.pdf', bbox_inches='tight', format='pdf') plt.savefig('Al_vpdata.png', dpi=300, bbox_inches='tight', format='png')
上述代码实现的插值函数完全满足需求:
- 280K~500K范围内的插值结果在对数坐标下与原始数据点完全重合
- 低于280K的区域统一输出280K对应的蒸气压数值
- 高于500K的区域统一输出500K对应的蒸气压数值
内容的提问来源于stack exchange,提问作者tjsmert44
相关产品推荐
相关产品推荐

