You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过插值方法将任意Numpy NDArray调整为指定新形状?

解决任意维度Numpy数组的插值缩放问题

嗨,这个问题我之前在使用PySide6做体绘制的时候刚好踩过坑,现在把解决方案整理出来分享给大家!

背景回顾

当时我遇到的情况是:PySide6的体绘制功能对输入纹理有个隐藏要求——各维度的长度必须是2的幂,但官方文档里并没有明确说明这一点。所以第一步得先把原数组的形状转换成符合要求的目标形状,用Numpy就能轻松计算:

import numpy as np
old_shape = (123, 456, 78)  # 示例原始数组形状
new_shape = np.power(2, np.ceil(np.log2(old_shape))).astype(int)

搞定目标形状后,核心问题就变成了:如何通过插值方法,把任意形状的Numpy NDArray缩放成指定的目标形状?我尝试了scipy的RegularGridInterpolator,亲测有效,下面是具体的实现步骤。

具体实现方案

1. 创建插值器实例

首先需要为原数组的每个维度生成对应的坐标网格,然后基于原数组创建插值器:

from scipy.interpolate import RegularGridInterpolator

# 为每个维度生成原始坐标点(从0到维度长度-1均匀分布)
original_coords = [np.linspace(0, dim - 1, dim) for dim in old_shape]
# 初始化插值器,这里可以选择插值方法:'linear'(线性插值)、'nearest'(最近邻)、'cubic'(三次插值)
interpolator = RegularGridInterpolator(original_coords, original_array, method='linear')

2. 生成目标网格坐标

接下来要生成对应目标形状的坐标网格,确保坐标范围和原数组保持一致:

# 生成目标每个维度的坐标点
target_coords = [np.linspace(0, dim - 1, new_dim) for dim, new_dim in zip(old_shape, new_shape)]
# 构建多维网格(注意用'ij'索引保持和数组维度顺序一致)
target_grid = np.meshgrid(*target_coords, indexing='ij')
# 把网格转换成插值器需要的格式:(样本数, 维度数)
target_points = np.stack([grid.ravel() for grid in target_grid], axis=1)

3. 执行插值并重塑形状

最后调用插值器计算结果,再把一维的插值结果重塑成目标形状:

# 执行插值计算
scaled_array = interpolator(target_points)
# 重塑为目标形状
scaled_array = scaled_array.reshape(new_shape)

额外小贴士

  • 插值方法选择:如果追求计算速度,优先选'nearest';如果需要更平滑的缩放效果,选'linear'或者'cubic'(注意高维场景下三次插值的计算量会显著增加)
  • 通用性:这个方案支持任意维度的数组,不管是2D图像、3D体数据还是更高维的数组都适用
  • 替代方案:如果不想依赖scipy,2D场景可以用OpenCV的cv2.resize,单维度可以用Numpy的np.interp,但RegularGridInterpolator是最省心的通用解决方案

内容的提问来源于stack exchange,提问作者Ruben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 14:33:16