使用scipy.interpolate.interpn实现转置时结果不符的问题排查
问题核心:scipy插值函数的坐标输入顺序与数组轴的对应关系
你的问题出在混淆了空间坐标映射和scipy.ndimage.map_coordinates(及同类插值函数)的轴坐标输入规则,具体如下:
关键规则澄清
map_coordinates的第二个参数coords是一个列表,其中每个元素对应原数组的一个轴,用来指定所有新位置在该轴上的坐标。换句话说:
- 若原三维数组
arr的轴0对应空间x、轴1对应空间y、轴2对应空间z(即arr[x, y, z]),那么coords[0]必须是所有新点对应的原x坐标,coords[1]是原y坐标,coords[2]是原z坐标。
你的坐标映射推导错误
你定义的新空间坐标是x'=z, y'=x, z'=y,即新数组的(x', y', z')对应原数组的(x=y', y=z', z=x')。但你可能直接将coords设为[x', y', z'] = [z, x, y],这是错误的——因为这个coords对应的是:
coords[0] = z→ 原x轴坐标取z(新x')coords[1] = x→ 原y轴坐标取x(新y')coords[2] = y→ 原z轴坐标取y(新z')
这实际对应的是原数组轴的映射为(2, 0, 1)的反向,最终得到的是(1, 2, 0)的转置结果,和你看到的现象一致。
正确的坐标映射实现
假设我们生成一个测试数组,先明确轴与空间坐标的对应:
import numpy as np from scipy.ndimage import map_coordinates # 原数组:轴0=x,轴1=y,轴2=z,形状(3,3,3) arr = np.arange(27).reshape(3,3,3) # 预期转置:arr.transpose(2, 0, 1) → 新轴0=原z(轴2),新轴1=原x(轴0),新轴2=原y(轴1) expected = arr.transpose(2, 0, 1)
要通过map_coordinates实现相同效果,需要构造新空间坐标的网格,并按原数组轴顺序生成coords:
# 生成新数组的网格坐标(x', y', z'),对应新轴0,1,2 x_prime, y_prime, z_prime = np.meshgrid(np.arange(3), np.arange(3), np.arange(3), indexing='ij') # 原数组的x坐标 = y'(因为y'=x),原y坐标=z'(因为z'=y),原z坐标=x'(因为x'=z) coords = [y_prime, z_prime, x_prime] # 执行插值(用order=0避免插值模糊,方便对比) result = map_coordinates(arr, coords, order=0, mode='constant') # 验证是否与预期一致 print(np.array_equal(result, expected)) # 输出True
总结疏漏点
- 没有明确
map_coordinates的coords参数是按原数组的轴顺序输入,而非直接按新空间坐标的定义输入; - 混淆了空间坐标标签(x/y/z)和数组轴编号(0/1/2)的对应关系,导致坐标映射顺序完全颠倒。
内容的提问来源于stack exchange,提问作者TurbulentReflections
相关产品推荐
相关产品推荐

