una transpuesta recorrer multiplicar matriz matrices funcion elementos ejemplos crear con array agregar python arrays optimization numpy dimensions

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