numpy数组移轴、换轴之差

numpy 与改变数组轴序有关的函数有三:

当想将某轴移去某位置时,应用 moveaxis。情景如医疗图像中 CT、MRI 的形状是 [H, W, L] 三维的,预处理时想沿某维 slice 之,为代码通用,想将 slice axis 移去 axis 0,然后总是沿 axis 0 slice。

此时一个隐藏的 bug 是:以为三维数组移轴用 swapaxes 也行,其实不然!这是混淆了「轴标(此轴叫数字几)」与「轴位(此轴排第几)」所致。更高维(如四维数组 [n, H, W, L])时此差别就明显了,但三维时有些迷惑性。

本文对比用 swapaxes 与 moveaxis 操作三、四维数组时的差异。另因 moveaxis 页面显示 New in version 1.11.0.,似乎此版本之后的 numpy 才有 moveaxis,故展示一种用 transpose 实现 moveaxis 的写法。

Code

import numpy as np

def transpose_as_moveaxis(arr, src_axis, dest_axis):
	"""用 transpose 实现 moveaxis"""
    if src_axis == dest_axis:
        return arr
    axes = list(range(arr.ndim))
    if src_axis < 0:
        src_axis = arr.ndim + src_axis
    if dest_axis < 0:
        dest_axis = arr.ndim + dest_axis
    assert src_axis >= 0 and dest_axis >= 0
    _fv = axes.pop(src_axis)
    axes.insert(dest_axis, _fv)
    return np.transpose(arr, axes)

print("3d")
x3 = np.zeros((1, 2, 3))
for f, t in zip(
    [0, 0, 1, 1, 2, 2],
    [1, 2, 0, 2, 0, 1]
):
    print('\t', f, '->', t)
    print(np.swapaxes(x3, f, t).shape)
    print(transpose_as_moveaxis(x3, f, t).shape)
    print(np.moveaxis(x3, f, t).shape)

print("4d")
x4 = np.zeros((1, 2, 3, 4))
print(np.swapaxes(x4, 1, -1).shape)
print(transpose_as_moveaxis(x4, 1, -1).shape)
print(np.moveaxis(x4, 1, -1).shape)

输出:

3d
         0 -> 1
(2, 1, 3)
(2, 1, 3)
(2, 1, 3)
         0 -> 2
(3, 2, 1)
(2, 3, 1)
(2, 3, 1)
         1 -> 0
(2, 1, 3)
(2, 1, 3)
(2, 1, 3)
         1 -> 2
(1, 3, 2)
(1, 3, 2)
(1, 3, 2)
         2 -> 0
(3, 2, 1)
(3, 1, 2)
(3, 1, 2)
         2 -> 1
(1, 3, 2)
(1, 3, 2)
(1, 3, 2)

4d
(1, 4, 3, 2)
(1, 3, 4, 2)
(1, 3, 4, 2)

可见,对 3d 数组,在 0 -> 22 -> 0 时 swapaxes 效果都与 moveaxis 同,4d 时此差别更容易想明白。

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值