¿Explicación clara y autorizada de los números del eje numpy?

Me estoy confundiendo con explicaciones contradictorias de lo que significa exactamente el término eje en numpy y cómo se numeran estas construcciones.

Aquí hay una explicación:
Los ejes se definen para matrices con más de una dimensión.
Una matriz bidimensional tiene dos ejes correspondientes:
el primero se ejecuta verticalmente hacia abajo a través de filas (eje 0), y
el segundo se ejecuta horizontalmente a través de columnas (eje 1).

Entonces, en esta matriz de 3×4 …

>>> b = np.arange(12).reshape(3,4) >>> b array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) 

(eje 0) son las 3 filas
(eje 1) son las 4 columnas.

Así que la regla podría ser …

En una matriz MxN, (el eje 0) es M y (el eje 1) es N.

¿Es esto correcto?

Entonces, en una matriz tridimensional, AxBxC (eje 0) es A
(eje 1) es B
(eje 2) es C

¿Es esto correcto?

Todo lo que dijiste es correcto, con la excepción de

Los ejes se definen para matrices con más de una dimensión.

Los ejes también se definen para arreglos unidimensionales, solo hay uno de ellos (es decir, el eje 0).


Una forma intuitiva de pensar en los ejes es considerar qué sucede cuando se aplica una operación de reducción sobre un eje, como la sum. Por ejemplo, supongamos que tengo una matriz x :

 x = np.arange(60).reshape(3, 4, 5) 

Si x.sum(0) estoy “colapsando” x sobre la primera dimensión (es decir, el eje 0), así que termino con una matriz (4, 5) . Del mismo modo, x.sum(1) me da una matriz (3, 5) y x.sum(2) me da una matriz (3, 4) .

Un índice entero en un solo eje de x también me dará una salida con un eje menos. Por ejemplo, x[0, :, :] me da la primera “fila” de x , que tiene forma (4, 5) , x[:, 0, :] me da la primera “columna” con forma (3, 5) , y x[:, :, 0] me da el primer corte en la tercera dimensión de x con forma (3, 4) .

Aunque es posible imaginar esto en 3D, personalmente creo que es difícil imaginarlo cuando vamos a 4D o 5D … Entonces, decido rendirme, pero más bien pienso en esto desde una perspectiva de implementación. Básicamente, tiene un número N de bucle nested, y si queremos reducir un eje específico, simplemente trabajamos en el bucle for de ese eje. Por ejemplo, si se le da un tensor de 3x3x3, axis = 0 es el bucle for de [ i ] [x] [x], axis = 1 es bucle a [x] [ i ] [x], axis = 2 is to bucle a [x] [x] [ i ]. 4D, 5D, … deberían tener la misma forma.

 def my_reduce_max(a, axis=0): b = [[-1 for _ in range(3)] for _ in range(3)] for j in range(3): for k in range(3): tmp_max = -1 for i in range(3): if axis == 0: get_value = a[i][j][k] elif axis == 1: get_value = a[j][i][k] else: get_value = a[j][k][i] tmp_max = max(get_value, tmp_max) b[j][k] = tmp_max return b a = np.arange(27).reshape((3,3,3)) print(a) my_reduce_max(a, 2) 

Si alguien necesita una idea clara, aquí está la foto:

Numpy Axis 0 y Axis 1