python - transpuesta - Intercambiando las dimensiones de una matriz numpy
recorrer una matriz en python (4)
Me gustaría hacer lo siguiente:
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]
Sin el uso de bucles. Al final, tanto A como B contienen la misma información pero se indexan de manera diferente.
Debo señalar que las dimensiones 1,2,3 y 4 pueden ser iguales o diferentes. Así que un numpy.reshape () parece difícil.
La forma canónica de hacer esto en numpy sería usar el argumento de permutación opcional de np.transpose
. En su caso, para pasar de klij
a klij
, la permutación es (2, 3, 0, 1)
, por ejemplo:
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)
Me gustaría ver numpy.ndarray.shape y 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]
Por "sin el uso de bucles" asumo que quiere decir "sin el uso de bucles anidados", por supuesto. A menos que haya un número incorporado que haga esto, creo que esta es tu mejor apuesta.
Podrías rollaxis
dos veces:
>>> 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
O quizás swapaxes
dos veces es más fácil de seguir:
>>> 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
Tenga en cuenta: la respuesta de Jaime es mejor. NumPy proporciona np.transpose
precisamente para este propósito.
O utilice np.einsum ; esta es quizás una perversión de su propósito, pero la sintaxis es bastante buena:
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