¿Cómo funciona numpy.newaxis y cuándo usarlo?

187

Cuando lo intento

numpy.newaxis

el resultado me da un marco gráfico de 2-d con eje x de 0 a 1. Sin embargo, cuando trato numpy.newaxisde cortar un vector,

vector[0:4,]
[ 0.04965172  0.04979645  0.04994022  0.05008303]
vector[:, np.newaxis][0:4,]
[[ 0.04965172]
[ 0.04979645]
[ 0.04994022]
[ 0.05008303]]

¿Es lo mismo excepto que cambia un vector de fila a un vector de columna?

En general, ¿de qué sirve numpy.newaxisy en qué circunstancias deberíamos usarlo?

Yue Harriet Huang
fuente
1
except that it changes a row vector to a column vector? El primer ejemplo no es un vector de fila. Ese es un concepto matlab. En python es solo un vector unidimensional sin concepto de fila o columna. Los vectores de fila o columna son bidimensionales, como el segundo ejemplo
endolito el

Respuestas:

331

En pocas palabras, numpy.newaxisse usa para aumentar la dimensión de la matriz existente en una dimensión más , cuando se usa una vez . Así,

  • La matriz 1D se convertirá en una matriz 2D

  • La matriz 2D se convertirá en una matriz 3D

  • La matriz 3D se convertirá en una matriz 4D

  • La matriz 4D se convertirá en una matriz 5D

y así..

Aquí hay una ilustración visual que muestra la promoción de una matriz 1D a matrices 2D.

visualización de canva newaxis


Escenario 1 : np.newaxispuede ser útil cuando desea convertir explícitamente una matriz 1D en un vector de fila o un vector de columna , como se muestra en la imagen de arriba.

Ejemplo:

# 1D array
In [7]: arr = np.arange(4)
In [8]: arr.shape
Out[8]: (4,)

# make it as row vector by inserting an axis along first dimension
In [9]: row_vec = arr[np.newaxis, :]     # arr[None, :]
In [10]: row_vec.shape
Out[10]: (1, 4)

# make it as column vector by inserting an axis along second dimension
In [11]: col_vec = arr[:, np.newaxis]     # arr[:, None]
In [12]: col_vec.shape
Out[12]: (4, 1)

Escenario-2 : cuando queremos hacer uso de la transmisión de numpy como parte de alguna operación, por ejemplo, al agregar algunas matrices.

Ejemplo:

Supongamos que desea agregar las siguientes dos matrices:

 x1 = np.array([1, 2, 3, 4, 5])
 x2 = np.array([5, 4, 3])

Si intenta agregarlos así, NumPy generará lo siguiente ValueError:

ValueError: operands could not be broadcast together with shapes (5,) (3,)

En esta situación, puede usar np.newaxispara aumentar la dimensión de una de las matrices para que NumPy pueda transmitir .

In [2]: x1_new = x1[:, np.newaxis]    # x1[:, None]
# now, the shape of x1_new is (5, 1)
# array([[1],
#        [2],
#        [3],
#        [4],
#        [5]])

Ahora, agregue:

In [3]: x1_new + x2
Out[3]:
array([[ 6,  5,  4],
       [ 7,  6,  5],
       [ 8,  7,  6],
       [ 9,  8,  7],
       [10,  9,  8]])

Alternativamente, también puede agregar un nuevo eje a la matriz x2:

In [6]: x2_new = x2[:, np.newaxis]    # x2[:, None]
In [7]: x2_new     # shape is (3, 1)
Out[7]: 
array([[5],
       [4],
       [3]])

Ahora, agregue:

In [8]: x1 + x2_new
Out[8]: 
array([[ 6,  7,  8,  9, 10],
       [ 5,  6,  7,  8,  9],
       [ 4,  5,  6,  7,  8]])

Nota : Observe que obtenemos el mismo resultado en ambos casos (pero uno es la transposición del otro).


Escenario-3 : Esto es similar al escenario-1. Pero, puede usar np.newaxismás de una vez para promover la matriz a dimensiones más altas. Tal operación a veces es necesaria para matrices de orden superior ( es decir, tensores ).

Ejemplo:

In [124]: arr = np.arange(5*5).reshape(5,5)

In [125]: arr.shape
Out[125]: (5, 5)

# promoting 2D array to a 5D array
In [126]: arr_5D = arr[np.newaxis, ..., np.newaxis, np.newaxis]    # arr[None, ..., None, None]

In [127]: arr_5D.shape
Out[127]: (1, 5, 5, 1, 1)

Más información sobre np.newaxis vs np.reshape

newaxis También se llama como un pseudo-índice que permite la adición temporal de un eje en una matriz múltiple.

np.newaxisusa el operador de corte para recrear la matriz mientras que np.reshapela forma a la disposición deseada (suponiendo que las dimensiones coincidan; y esto es imprescindible para reshapeque ocurra).

Ejemplo

In [13]: A = np.ones((3,4,5,6))
In [14]: B = np.ones((4,6))
In [15]: (A + B[:, np.newaxis, :]).shape     # B[:, None, :]
Out[15]: (3, 4, 5, 6)

En el ejemplo anterior, insertamos un eje temporal entre el primer y el segundo eje de B(para usar la transmisión). Aquí se rellena un eje que falta np.newaxispara hacer que la operación de transmisión funcione.


Consejo general : También puede usarNoneen lugar denp.newaxis; Estos son, de hecho, los mismos objetos .

In [13]: np.newaxis is None
Out[13]: True

PD: vea también esta excelente respuesta: newaxis vs rehape para agregar dimensiones

kmario23
fuente
3
¿Qué tipo de operación es x1_new + x2? Es extraño para mí porque pensé que dos matrices solo se pueden agregar si tienen las mismas dimensiones (o si una de ellas es solo un escalar).
Stephen
2
@Stephen Como también señalé en la respuesta, es por NumPy Broadcasting.
kmario23
2
Esta es una explicación increíble
Valdrinium
2
@valdrinit contento de que es útil para usted :)
kmario23
1
@ kmario23 De hecho, la atribución está oculta en la última oración del artículo, no es de extrañar que no la haya visto. Considero que es un plagio límite incluso con esta atribución. En mi libro, la copia palabra por palabra solo es aceptable si es el mismo autor que publica en diferentes plataformas. Esperaba algo mejor de Medium.
Chiraz BenAbdelkader
29

¿Qué es np.newaxis?

El np.newaxises solo un alias para la constante de Python None, lo que significa que donde sea que use np.newaxistambién podría usar None:

>>> np.newaxis is None
True

Es más descriptivo si lees el código que usa en np.newaxislugar de None.

¿Cómo usarlo np.newaxis?

El np.newaxisse usa generalmente con rebanado. Indica que desea agregar una dimensión adicional a la matriz. La posición de lanp.newaxis representa donde quiero agregar dimensiones.

>>> import numpy as np
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a.shape
(10,)

En el primer ejemplo, uso todos los elementos de la primera dimensión y agrego una segunda dimensión:

>>> a[:, np.newaxis]
array([[0],
       [1],
       [2],
       [3],
       [4],
       [5],
       [6],
       [7],
       [8],
       [9]])
>>> a[:, np.newaxis].shape
(10, 1)

El segundo ejemplo agrega una dimensión como primera dimensión y luego usa todos los elementos de la primera dimensión de la matriz original como elementos en la segunda dimensión de la matriz de resultados:

>>> a[np.newaxis, :]  # The output has 2 [] pairs!
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
>>> a[np.newaxis, :].shape
(1, 10)

Del mismo modo, puede usar múltiples np.newaxispara agregar múltiples dimensiones:

>>> a[np.newaxis, :, np.newaxis]  # note the 3 [] pairs in the output
array([[[0],
        [1],
        [2],
        [3],
        [4],
        [5],
        [6],
        [7],
        [8],
        [9]]])
>>> a[np.newaxis, :, np.newaxis].shape
(1, 10, 1)

¿Hay alternativas a np.newaxis?

Hay otra funcionalidad muy similar en NumPy: np.expand_dimsque también se puede usar para insertar una dimensión:

>>> np.expand_dims(a, 1)  # like a[:, np.newaxis]
>>> np.expand_dims(a, 0)  # like a[np.newaxis, :]

Pero dado que solo inserta 1s en la matriz, shapetambién reshapepuede agregar estas dimensiones:

>>> a.reshape(a.shape + (1,))  # like a[:, np.newaxis]
>>> a.reshape((1,) + a.shape)  # like a[np.newaxis, :]

La mayoría de las veces np.newaxis es la forma más fácil de agregar dimensiones, pero es bueno conocer las alternativas.

Cuándo usar np.newaxis ?

En varios contextos es útil agregar dimensiones útiles:

  • Si los datos deben tener un número especificado de dimensiones. Por ejemplo, si desea usar matplotlib.pyplot.imshowpara mostrar una matriz 1D.

  • Si quieres que NumPy difunda matrices. Mediante la adición de una dimensión que podría conseguir, por ejemplo, la diferencia entre todos los elementos de un array: a - a[:, np.newaxis]. Esto funciona porque las operaciones NumPy transmiten comenzando con la última dimensión 1 .

  • Para agregar una dimensión necesaria para que NumPy pueda transmitir matrices. Esto funciona porque cada dimensión de longitud 1 simplemente se transmite a la longitud de la dimensión 1 correspondiente de la otra matriz.


1 Si desea leer más sobre las reglas de transmisión, la documentación de NumPy sobre ese tema es muy buena. También incluye un ejemplo con np.newaxis:

>>> a = np.array([0.0, 10.0, 20.0, 30.0])
>>> b = np.array([1.0, 2.0, 3.0])
>>> a[:, np.newaxis] + b
array([[  1.,   2.,   3.],
       [ 11.,  12.,  13.],
       [ 21.,  22.,  23.],
       [ 31.,  32.,  33.]])
MSeifert
fuente
No veo la diferencia entre el segundo y tercer casos de uso; Ambos tratan de permitir que NumPy difunda una matriz como parte de alguna operación. De lo contrario, sería útil agregar un ejemplo para el tercer caso de uso para aclarar el punto.
Chiraz BenAbdelkader
@ChirazBenAbdelkader Sí, la distinción no es realmente tan distinta. No estoy seguro de si debo eliminar el tercer punto o fusionarlo en el segundo.
MSeifert
9

Comenzaste con una lista unidimensional de números. Una vez que lo usó numpy.newaxis, lo convirtió en una matriz bidimensional, que consta de cuatro filas de una columna cada una.

Entonces podría usar esa matriz para la multiplicación de la matriz, o involucrarla en la construcción de una matriz 4 xn más grande.

Kevin
fuente
5

newaxisEl objeto en la tupla de selección sirve para expandir las dimensiones de la selección resultante en una dimensión de unidad de longitud .

No es solo la conversión de matriz de fila a matriz de columna.

Considere el siguiente ejemplo:

In [1]:x1 = np.arange(1,10).reshape(3,3)
       print(x1)
Out[1]: array([[1, 2, 3],
               [4, 5, 6],
               [7, 8, 9]])

Ahora agreguemos una nueva dimensión a nuestros datos,

In [2]:x1_new = x1[:,np.newaxis]
       print(x1_new)
Out[2]:array([[[1, 2, 3]],

              [[4, 5, 6]],

              [[7, 8, 9]]])

Puede ver que newaxisagregó la dimensión adicional aquí, x1 tenía dimensión (3,3) y X1_new tiene dimensión (3,1,3).

Cómo nuestra nueva dimensión nos permite realizar diferentes operaciones:

In [3]:x2 = np.arange(11,20).reshape(3,3)
       print(x2)
Out[3]:array([[11, 12, 13],
              [14, 15, 16],
              [17, 18, 19]]) 

Al agregar x1_new y x2, obtenemos:

In [4]:x1_new+x2
Out[4]:array([[[12, 14, 16],
               [15, 17, 19],
               [18, 20, 22]],

              [[15, 17, 19],
               [18, 20, 22],
               [21, 23, 25]],

              [[18, 20, 22],
               [21, 23, 25],
               [24, 26, 28]]])

Por lo tanto, newaxisno es solo la conversión de la matriz de fila a columna. Aumenta la dimensión de la matriz, lo que nos permite realizar más operaciones en ella.

Duro hundiwala
fuente
1
No es solo matriz, funciona con cualquiera ndarrayen la terminología NumPy.
kmario23