如何从Numpy数组插值查询多值(实现Matlab interp1的previous模式)
多列前值插值的Python简洁实现
你之前调用interp1d报错的核心原因是fill_value参数格式不匹配:当传入多列y值时,若用(0, 0)格式的二元组指定上下限填充值,需要每个元素的维度和y的非插值轴维度匹配,直接传标量0即可让所有列的上下限填充值都为0,不会触发维度错误。
方案1:直接用interp1d实现多列插值
无需逐列定义插值器,一行即可完成多列适配,适配任意列数的输入数组:
import numpy as np from scipy.interpolate import interp1d # Time, q_in, x_in, y_in inputArray = np.array(([3600, 60, 50, 40], [3700, 0, 50, 40], [7260, 200, 20, 10])) t_current = 3650 # 直接传入多列y值,fill_value传标量0即可 itp = interp1d(inputArray[:,0], inputArray[:,1:], kind='previous', bounds_error=False, fill_value=0) inputVector = itp(t_current)
运行输出为array([60., 50., 40.]),和预期一致。
方案2:用numpy原生方法实现,性能更高
如果不想依赖scipy的插值器,可以用searchsorted直接定位前值索引,效率更高,尤其适合大数组、多列的场景:
import numpy as np inputArray = np.array(([3600, 60, 50, 40], [3700, 0, 50, 40], [7260, 200, 20, 10])) t_current = 3650 # 定位第一个大于当前时间的索引,减1即为最近前值的索引 idx = np.searchsorted(inputArray[:,0], t_current, side='right') - 1 # 索引合法则取对应行,否则返回全0 inputVector = inputArray[idx, 1:] if idx >= 0 else np.zeros(inputArray.shape[1]-1)
方案3:用pandas实现,适合批量查询场景
如果需要同时查询多个时间点的前值,用pandas的merge_asof逻辑更清晰:
import pandas as pd import numpy as np inputArray = np.array(([3600, 60, 50, 40], [3700, 0, 50, 40], [7260, 200, 20, 10])) t_list = [3650, 3750, 3000] # 支持同时查询多个时间点 input_df = pd.DataFrame(inputArray, columns=['time'] + [f'col_{i}' for i in range(inputArray.shape[1]-1)]) query_df = pd.DataFrame({'time': t_list}) res = pd.merge_asof(query_df, input_df, on='time', direction='backward').fillna(0).iloc[:,1:].values
以上三种方案都不需要逐列编写逻辑,不管输入数组是3列还是50列都可以直接复用。
内容的提问来源于stack exchange,提问作者winkmal
相关产品推荐
相关产品推荐

