scipy.interpolate.bisplrep返回NaN值的原因是什么?
解决bisplrep返回NaN及构建可调用插值函数的问题
问题根源分析
bisplrep返回NaN的核心原因是iv_interpol中存在NaN值——griddata的linear方法在原始数据凸包外的点会生成NaN,而bisplrep无法处理包含缺失值的输入数据。
修复方案与优化代码
步骤1:清理输入数据,直接用原始有效数据构建B样条
跳过griddata中间步骤,直接把原始的有效(T,K,vol)数据传入bisplrep,避免引入额外NaN:
import numpy as np import pandas as pd from scipy.interpolate import bisplrep, bisplev # 读取数据 vol = pd.read_csv('data1.csv', index_col='dte') # 提取原始有效数据(剔除NaN) T = vol.index.values K = vol.columns.values T_mesh, K_mesh = np.meshgrid(T, K) vol_values = vol.values.T # 转置匹配网格维度 # 筛选有效数据点 valid_mask = ~np.isnan(vol_values) valid_T = T_mesh[valid_mask] valid_K = K_mesh[valid_mask] valid_vol = vol_values[valid_mask] # 构建B样条(可调整kx, ky参数控制平滑度,默认是3次样条) tck = bisplrep(valid_T, valid_K, valid_vol, kx=3, ky=3)
步骤2:封装可调用的插值函数
基于tck创建一个支持单个或批量点输入的函数:
def znew(a, b): # 兼容单个数值、列表或数组类型的输入 return bisplev(a, b, tck) # 测试调用示例 print(znew(10, 100)) # 单个点插值 print(znew([10,20], [100,110])) # 批量点插值
额外补充
如果必须保留griddata预处理步骤,需要先补全iv_interpol中的NaN值,示例:
iv_interpol = griddata((valid_Ti, valid_Ki), valid_vol, (Ti, Ki), method='linear') # 用最近邻法补全凸包外的NaN nan_mask = np.isnan(iv_interpol) iv_interpol[nan_mask] = griddata((valid_Ti, valid_Ki), valid_vol, (Ti[nan_mask], Ki[nan_mask]), method='nearest') # 展平网格数据后传入bisplrep tck = bisplrep(Ti.flatten(), Ki.flatten(), iv_interpol.flatten())
内容的提问来源于stack exchange,提问作者Xerium
相关产品推荐
相关产品推荐

