vectores una tutorial transpuesta multiplicar matriz matrices inversa espaƱol ejemplos como calcular bidimensionales arreglos python arrays numpy

python - tutorial - obteniendo la diagonal opuesta de una matriz numpy



transpuesta de una matriz en python numpy (3)

Así que en matrices numpy hay una función incorporada para obtener los índices diagonales, pero parece que no puedo encontrar la forma de obtener la diagonal comenzando desde la parte superior derecha en lugar de la superior izquierda.

Este es el código normal para comenzar desde la parte superior izquierda:

>>> import numpy as np >>> array = np.arange(25).reshape(5,5) >>> diagonal = np.diag_indices(5) >>> array array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19], [20, 21, 22, 23, 24]]) >>> array[diagonal] array([ 0, 6, 12, 18, 24])

Entonces, ¿qué uso si quiero que vuelva?

array([ 4, 8, 12, 16, 20])


Ahi esta

In [47]: np.diag(np.fliplr(array)) Out[47]: array([ 4, 8, 12, 16, 20])

o

In [48]: np.diag(np.rot90(array)) Out[48]: array([ 4, 8, 12, 16, 20])

De los dos, np.diag(np.fliplr(array)) es más rápido:

In [50]: %timeit np.diag(np.fliplr(array)) 100000 loops, best of 3: 4.29 us per loop In [51]: %timeit np.diag(np.rot90(array)) 100000 loops, best of 3: 6.09 us per loop


Aquí hay dos ideas:

step = len(array) - 1 # This will make a copy array.flat[step:-step:step] # This will make a veiw array.ravel()[step:-step:step]


Aquí hay una forma simple de usar el recorte numpy. Personalmente no me resulta muy duro para los ojos (¡pero concedo que fliplr es un poco más descriptivo!).

Solo para resaltar la contribución de este ejemplo a las respuestas existentes, ejecuté el mismo punto de referencia simple.

In [1]: import numpy as np In [3]: X = np.random.randint(0, 10, (5, 5)) In [4]: X Out[4]: array([[7, 2, 7, 3, 7], [8, 4, 5, 9, 6], [0, 2, 9, 0, 4], [8, 2, 1, 0, 3], [3, 1, 0, 7, 0]]) In [5]: Y = X[:, ::-1] In [6]: Z1 = np.diag(Y) In [7]: Z1 Out[7]: array([7, 9, 9, 2, 3])

Ahora para comparar con la solución más rápida actual dada.

In [8]: step = len(X) - 1 In [9]: Z2 = np.take(X, np.arange(step, X.size-1, step)) In [10]: Z2 Out[10]: array([7, 9, 9, 2, 3]) In [11]: np.array_equal(Z1, Z2) Out[11]: True

Puntos de referencia

In [12]: %timeit np.diag(X[:, ::-1]) 1.92 µs ± 29.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) In [13]: %timeit step = len(X) - 1; np.take(X, np.arange(step, X.size-1, step)) 2.21 µs ± 246 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Las comparaciones iniciales indican que mi solución es además de complejidad lineal, mientras que usar la solución del segundo paso no es:

In [14]: big_X = np.random.randint(0, 10, (10000, 10000)) In [15]: %timeit np.diag(big_X[:, ::-1]) 2.15 µs ± 96.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) In [16]: %timeit step = len(big_X) - 1; np.take(big_X, np.arange(step, big_X.size-1, step)) 100 µs ± 1.85 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

Generalmente uso este método para voltear imágenes (reflejarlas) o para convertir entre el formato de opencv (canales, altura, ancho) al formato de matplotlib (altura, anchura, canales) . Entonces, para una imagen tridimensional, simplemente se flipped = image[:, :, ::-1] . Por supuesto, puede generalizarlo para voltear a lo largo de cualquier dimensión, colocando la parte ::-1 en la dimensión deseada.