NumPy数组的重新排序

8
我想重新排列我的numpy数组的维度。下面的代码可以实现,但速度太慢。
for i in range(image_size):
    for j in range(image_size):
        for k in range(3):
            new_im[k, i, j] = im[i, j, k]

接下来,我将对new_im进行向量化处理:

new_im_vec = new_im.reshape(image_size**2 * 3)

话虽如此,但我不需要new_im,只需要得到new_im_vec。有更好的方法吗?图像大小约为256。


如果您正在使用Python2,可以使用xrange代替range - jh314
3个回答

11

看看rollaxis函数,它可以将轴移动,使你能够在单个命令中重新排列数组。如果im的形状是i,j,k

rollaxis(im, 2)
应该返回一个形状为 k, i, j 的数组。
之后,您可以展平您的数组,使用ravel函数来实现这个目的很清晰。将所有这些放在一起,你可以得到一个漂亮的一行代码:
new_im_vec = ravel(rollaxis(im, 2))

太棒了!它可以工作。我需要做的另一件事是在第一维中进行镜像。交换a [1,:,:]和a [3,:,:]。有这样的功能吗? - Mohammad Moghimi
1
如果我正确理解了你的问题,你可以使用flipud函数将数组沿水平轴翻转。a[::-1,:,:]也应该可以。 - Kyler Brown
2
+1 可能是最好的选择。为了完整起见,还有一种选项(我认为实际上被称为 np.rollaxis),即执行 np.transpose(im, (2, 0, 1))。另外需要注意的是,np.rollaxisnp.transpose 返回原始数据的视图,但在对该视图调用 flatten 时,可能会触发复制。 - Jaime

8
new_im = im.swapaxes(0,2).swapaxes(1,2) # First swap i and k, then i and j
new_im_vec = new_im.flatten() # Vectorize

这应该会更快,因为swapaxes返回数组上的视图,而不是复制元素。当然,如果你想跳过new_im,你可以在一行中完成,仅有flatten在进行任何复制。
new_im_vec = im.swapaxes(0,2).swapaxes(1,2).flatten()

swapaxes很棒!非常感谢! - duhaime

1
使用einops:
x = einops.rearrange(x, 'height width color -> color height width')

优点:

  • 您可以看到输入时轴的顺序
  • 您可以看到输出时轴的顺序
  • 您无需考虑需要采取的步骤(例如,无需记住轴滚动的方向)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接