简体   繁体   English

交换numpy数组的尺寸

[英]Swapping the dimensions of a numpy array

I would like to do the following: 我想做以下事情:

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]

without the use of loops. 不使用循环。 In the end both A and B contain the same information but indexed differently. 最后,A和B包含相同的信息,但索引不同。

I must point out that the dimension 1,2,3 and 4 can be the same or different. 我必须指出尺寸1,2,3和4可以相同或不同。 So a numpy.reshape() seems difficult. 所以numpy.reshape()似乎很难。

The canonical way of doing this in numpy would be to use np.transpose 's optional permutation argument. 在numpy中执行此操作的规范方法是使用np.transpose的可选置换参数。 In your case, to go from ijkl to klij , the permutation is (2, 3, 0, 1) , eg: 在你的情况下,从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)

Please note: Jaime's answer is better. 请注意: Jaime的答案更好。 NumPy provides np.transpose precisely for this purpose. NumPy为此提供np.transpose精确的np.transpose


Or use np.einsum ; 或者使用np.einsum ; this is perhaps a perversion of its intended purpose, but the syntax is quite nice: 这可能是其预期目的的歪曲,但语法非常好:

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

You could rollaxis twice: 你可以两次使用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

or maybe swapaxes twice is easier to follow: 或者两次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

I would look at numpy.ndarray.shape and itertools.product: 我会看看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]

By "without the use of loops" I'm assuming you mean "without the use of nested loops", of course. 通过“不使用循环”,我假设你的意思是“不使用嵌套循环”,当然。 Unless there's some numpy built-in that does this, I think this is your best bet. 除非有一些内置的numpy这样做,我认为这是你最好的选择。

One can also leverage numpy.moveaxis() for moving the required axes to desired locations. 还可以利用numpy.moveaxis() 所需的轴移动到所需的位置。 Here is an illustration, stealing the example from Jaime's answer : 这是一个例子,从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