Swapping the dimensions of a numpy array

前端 未结 5 1771
不思量自难忘°
不思量自难忘° 2020-12-09 14:37

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,         


        
相关标签:
5条回答
  • 2020-12-09 15:06

    The canonical way of doing this in numpy would be to use np.transpose's optional permutation argument. In your case, to go from ijkl to klij, the permutation is (2, 3, 0, 1), e.g.:

    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)
    
    0 讨论(0)
  • 2020-12-09 15:14

    One can also leverage numpy.moveaxis() for moving the required axes to desired locations. Here is an illustration, stealing the example from 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)
    
    0 讨论(0)
  • 2020-12-09 15:19

    I would look at numpy.ndarray.shape and 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.

    0 讨论(0)
  • 2020-12-09 15:23

    You could rollaxis twice:

    >>> 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:

    >>> 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
    
    0 讨论(0)
  • 2020-12-09 15:28

    Please note: Jaime's answer is better. NumPy provides np.transpose precisely for this purpose.


    Or use 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
    
    0 讨论(0)
提交回复
热议问题