Je voudrais faire ce qui suit:
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]
sans utiliser de boucles. En fin de compte, A et B contiennent les mêmes informations mais indexées différemment.
Je dois souligner que les dimensions 1, 2, 3 et 4 peuvent être identiques ou différentes. Un numpy.reshape () semble donc difficile.
Veuillez noter: la réponse de Jaime est mieux. NumPy fournit np.transpose
précisément à cet effet.
Ou utilisez np.einsum ; c'est peut-être une perversion de son objectif, mais la syntaxe est plutôt sympa:
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
La manière canonique de le faire en numpy serait d'utiliser np.transpose
argument de permutation facultatif. Dans votre cas, pour passer de ijkl
à klij
, la permutation est (2, 3, 0, 1)
, par exemple.:
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)
Vous pourriez rollaxis
deux fois:
>>> 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
ou peut-être swapaxes
deux fois est plus facile à suivre:
>>> 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
Je regarderais numpy.ndarray.shape et 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]
Par "sans utiliser de boucles", je suppose que vous voulez dire "sans utiliser de boucles imbriquées", bien sûr. À moins qu'il y ait un certain numpy intégré qui le fasse, je pense que c'est votre meilleur pari.
On peut également utiliser numpy.moveaxis()
pour se déplacer les axes requis aux emplacements souhaités. Voici une illustration, volant l'exemple de réponse de 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)