交换numpy数组的维度

iqih9akk  于 11个月前  发布在  其他
关注(0)|答案(6)|浏览(127)

我想做的是:

for i in dimension1:
  for j in dimension2:
    for k in dimension3:
      for l in dimension4:
        B[k,l,i,j] = A[i,j,k,l]

字符串
不使用循环。最后A和B都包含相同的信息,但索引不同。
我必须指出,维度1、2、3和4可以相同或不同。所以numpy.reshape()看起来很难。

pod7payv

pod7payv1#

在numpy中实现这一点的规范方法是使用np.transpose的可选置换参数。在您的情况下,要从ijklklij,置换是(2, 3, 0, 1),例如:

In [16]: a = np.empty((2, 3, 4, 5))

In [17]: b = np.transpose(a, (2, 3, 0, 1))

In [18]: b.shape
Out[18]: (4, 5, 2, 3)

字符串

watbbzwu

watbbzwu2#

请注意:Jaime's answer更好。NumPy为此提供了np.transpose
或者使用np.einsum;这可能是其预期目的的扭曲,但语法非常好:

In [195]: A = np.random.random((2,4,3,5))

In [196]: B = np.einsum('klij->ijkl', A)

In [197]: A.shape
Out[197]: (2, 4, 3, 5)

In [198]: B.shape
Out[198]: (3, 5, 2, 4)

In [199]: import itertools as IT    
In [200]: all(B[k,l,i,j] == A[i,j,k,l] for i,j,k,l in IT.product(*map(range, A.shape)))
Out[200]: True

字符串

rhfm7lfc

rhfm7lfc3#

你可以rollaxis两次:

>>> A = np.random.random((2,4,3,5))
>>> B = np.rollaxis(np.rollaxis(A, 2), 3, 1)
>>> A.shape
(2, 4, 3, 5)
>>> B.shape
(3, 5, 2, 4)
>>> from itertools import product
>>> all(B[k,l,i,j] == A[i,j,k,l] for i,j,k,l in product(*map(range, A.shape)))
True

字符串
或者swapaxes两次更容易理解:

>>> A = np.random.random((2,4,3,5))
>>> C = A.swapaxes(0, 2).swapaxes(1,3)
>>> C.shape
(3, 5, 2, 4)
>>> all(C[k,l,i,j] == A[i,j,k,l] for i,j,k,l in product(*map(range, A.shape)))
True

mtb9vblg

mtb9vblg4#

也可以利用numpy.moveaxis()将所需的轴 * 移动 * 到所需的位置。下面是一个示例,从Jaime's answer中窃取示例:

In [160]: a = np.empty((2, 3, 4, 5))

# move the axes that are originally at positions [0, 1] to [2, 3]
In [161]: np.moveaxis(a, [0, 1], [2, 3]).shape 
Out[161]: (4, 5, 2, 3)

字符串

wmomyfyw

wmomyfyw5#

我会看看numpy.ndarray.shape和itertools.product:

import numpy, itertools
A = numpy.ones((10,10,10,10))
B = numpy.zeros((10,10,10,10))

for i, j, k, l in itertools.product(*map(xrange, A.shape)):
    B[k,l,i,j] = A[i,j,k,l]

字符串
当然,我假设你说的“不使用循环”是指“不使用嵌套循环”。除非有numpy内置程序可以做到这一点,否则我认为这是你最好的选择。

r55awzrz

r55awzrz6#

Jaime的答案是正确的,np.transpose是解决方案。但他没有解释如何计算排列参数。所以,我想在这里解释如何正确计算它:
如果你有一个4维轴数组,比如:(i,j,k,l),你想把它们转置成(k,l,i,j),首先你必须对每个轴进行pythonically编号,所以在给定的例子中:“i”是axis=0,“j”是axis =1,“k”是axis=2,而“l”是axis=3,那么你应该保持原始的轴数,并将这些轴数排列成最终想要的轴排列,如:k应该被放置在轴=0中,并且k由数字2表示,因此2位于轴=0的位置,这给出=>(2,)...,并且通过对其他轴保持相同的条件,将获得(2,3,0,1)的置换变元。在计算排列参数时,很容易将 * 最终轴数 * 误认为是原始轴数,例如错误地考虑:“i”应该变成axis=2,“j”应该变成axis=3,“k”应该变成axis=0,而“l”应该变成axis=1,这 * 令人惊讶地 * 给出(2,3,0,但这种计算方式在其他情况下可能会给予错误的答案。例如,如果你要转置(i,j,k,l)转换为(i,k,l,j),第一种方法正确地计算出置换参数为(0,2,3,1),但第二种方法错误地计算出它为(0,3,1,2),如下图所示:

import numpy as np
A = np.ones((500,3,512,512))
# Changing A dimensions into (500,512,512,3)
B = np.transpose(A, (0,2,3,1))
C = np.transpose(A, (0,3,1,2))
print(np.shape(B))  # permutation is correct
print(np.shape(C))  # permutation is wrong

字符串
它打印:

size of B is: (500, 512, 512, 3)
size of C is: (500, 512, 3, 512)

相关问题