繁体   English   中英

交换numpy数组的尺寸

[英]Swapping the dimensions of a numpy array

我想做以下事情:

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()似乎很难。

在numpy中执行此操作的规范方法是使用np.transpose的可选置换参数。 在你的情况下,从ijklklij ,排列是(2, 3, 0, 1) klij (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)

请注意: Jaime的答案更好。 NumPy为此提供np.transpose精确的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

你可以两次使用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

我会看看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这样做,我认为这是你最好的选择。

还可以利用numpy.moveaxis() 所需的轴移动到所需的位置。 这是一个例子,从Jaime的答案中窃取了这个例子:

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM