寻求优雅方案:Numpy数组按指定步长扩展并线性插值
Numpy数组线性插值扩展的简洁实现
需求背景
需要对Numpy数组进行转换与扩展:行以0.1为增量扩展,列以1度为增量扩展,同时对数值执行线性插值。原实现依赖多层循环,代码冗余且效率较低,以下是更简洁的优化方案。
优化实现(纯Numpy)
import numpy as np # 生成样本数据集:10行(tp=0~9),12列(角度0~330,步长30) np.random.seed(42) # 固定种子方便结果复现 dataset = np.random.randint(1, 10, (10, 12)) tp_old = np.arange(10) angle_old = np.arange(0, 360, 30) # 1. 行方向插值:步长0.1,扩展为91行(tp=0,0.1,...,9.0) tp_new = np.linspace(0, 9, 91) # 对每一列在新tp坐标上做线性插值 row_interp = np.array([np.interp(tp_new, tp_old, dataset[:, col]) for col in range(dataset.shape[1])]).T # 2. 列方向插值:步长1度,扩展为360列(角度0~359),处理角度周期性 angle_old_full = np.concatenate([angle_old, [360]]) # 补充360°对应原0°的数值 dataset_full = np.concatenate([row_interp, row_interp[:, [0]]], axis=1) angle_new = np.arange(0, 360) # 对每一行在新角度坐标上做线性插值 final_data = np.array([np.interp(angle_new, angle_old_full, dataset_full[row, :]) for row in range(row_interp.shape[0])]) print(f"原始数据形状: {dataset.shape}") print(f"最终数据形状: {final_data.shape}") # 输出 (91, 360)
优化亮点
- 用Numpy原生
np.interp替代手动循环计算,代码更简洁,且底层C实现的效率远高于Python循环。 - 分离行、列插值逻辑,可读性更强,维护成本更低。
- 通过扩展角度坐标到360°,自然处理了角度周期性(330°到360°即0°的插值),无需单独编写末尾区间的处理代码。
- 避免了原代码中频繁的
vstack/column_stack数组拼接操作(这类操作会重复分配内存,大幅降低效率)。
进阶方案(Scipy 2D插值)
如果需要处理更复杂的规则网格插值场景,可使用Scipy的RegularGridInterpolator,代码更简洁:
from scipy.interpolate import RegularGridInterpolator # 构造2D插值器 interp = RegularGridInterpolator((tp_old, angle_old), dataset, bounds_error=False, fill_value=None) # 生成新的网格点 tp_new_2d, angle_new_2d = np.meshgrid(tp_new, angle_new, indexing='ij') points = np.stack([tp_new_2d.ravel(), angle_new_2d.ravel()], axis=1) # 执行插值 final_data_scipy = interp(points).reshape(tp_new.shape[0], angle_new.shape[0])
内容的提问来源于stack exchange,提问作者M LUY
相关产品推荐
相关产品推荐

