Como o numpy.newaxis funciona e quando usá-lo?

186

Quando eu tento

numpy.newaxis

o resultado fornece um quadro de plotagem 2D com eixo x de 0 a 1. No entanto, quando tento usar numpy.newaxispara fatiar um vetor,

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

É a mesma coisa, exceto que ele altera um vetor de linha para um vetor de coluna?

Geralmente, para que serve numpy.newaxise em que circunstâncias devemos usá-lo?

Yue Harriet Huang
fonte
1
except that it changes a row vector to a column vector? O primeiro exemplo não é um vetor de linha. Esse é um conceito do Matlab. Em python, é apenas um vetor unidimensional sem conceito de linha ou coluna. Vectores de linhas ou colunas são 2-dimensonal, como o segundo exemplo
endolith

Respostas:

330

Simplificando, numpy.newaxisé usado para aumentar a dimensão da matriz existente em mais uma dimensão , quando usado uma vez . Portanto,

  • Matriz 1D se tornará matriz 2D

  • Matriz 2D se tornará matriz 3D

  • Matriz 3D se tornará matriz 4D

  • Matriz 4D se tornará matriz 5D

e assim por diante..

Aqui está uma ilustração visual que mostra a promoção da matriz 1D para matrizes 2D.

visualização do newaxis canva


Cenário-1 : np.newaxispode ser útil quando você deseja converter explicitamente uma matriz 1D em um vetor de linha ou vetor de coluna , conforme mostrado na figura acima.

Exemplo:

# 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)

Cenário 2 : Quando queremos usar a transmissão numpy como parte de alguma operação, por exemplo, ao adicionar algumas matrizes.

Exemplo:

Digamos que você queira adicionar as duas matrizes a seguir:

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

Se você tentar adicioná-los assim, o NumPy aumentará o seguinte ValueError:

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

Nessa situação, você pode usar np.newaxispara aumentar a dimensão de uma das matrizes para que o NumPy possa 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]])

Agora adicione:

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

Como alternativa, você também pode adicionar um novo eixo à 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]])

Agora adicione:

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 obtemos o mesmo resultado nos dois casos (mas um é a transposição do outro).


Cenário-3 : É semelhante ao cenário-1. Porém, você pode usar np.newaxismais de uma vez para promover a matriz para dimensões mais altas. Essa operação às vezes é necessária para matrizes de ordem superior ( ou seja, tensores ).

Exemplo:

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)

Mais informações sobre np.newaxis vs np.reshape

newaxis também é chamado de pseudo-índice que permite a adição temporária de um eixo em uma multiarray.

np.newaxisusa o operador de fatiamento para recriar a matriz enquanto np.reshapemodela a matriz para o layout desejado (assumindo que as dimensões correspondam; e isso é necessário para reshapeque isso aconteça).

Exemplo

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)

No exemplo acima, inserimos um eixo temporário entre o primeiro e o segundo eixo de B(para usar a transmissão). Um eixo ausente é preenchido aqui usando np.newaxispara fazer a operação de transmissão funcionar.


Dica geral : Você também pode usarNoneno lugar denp.newaxis; Estes são de fato os mesmos objetos .

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

PS Veja também esta ótima resposta: newaxis vs remodelar para adicionar dimensões

kmario23
fonte
3
Que tipo de operação é x1_new + x2? É estranho para mim porque pensei que duas matrizes só podem ser adicionadas se tiverem as mesmas dimensões (ou se uma delas for realmente apenas um escalar).
Stephen
2
@ Stephen Como também observei na resposta, é por causa da NumPy Broadcasting.
precisa saber é o seguinte
2
Esta é uma explicação incrível
Valdrinium
2
@valdrinit contente que é útil para você :)
kmario23
1
@ kmario23 De fato, a atribuição está oculta na última frase do artigo, não admira que eu não tenha visto. Considero plágio limítrofe mesmo com essa atribuição. No meu livro, a cópia palavra por palavra só é aceitável se for o mesmo autor postando em plataformas diferentes. Eu esperava melhor do Medium.
Chiraz BenAbdelkader
29

O que é np.newaxis?

O np.newaxisé apenas um alias para a constante Python None, o que significa que, onde quer que você use, np.newaxisvocê também poderá usar None:

>>> np.newaxis is None
True

É apenas mais descritivo se você ler o código que usa em np.newaxisvez de None.

Como usar np.newaxis?

A np.newaxisé geralmente utilizada com o corte. Indica que você deseja adicionar uma dimensão adicional à matriz. A posição do np.newaxisrepresenta onde eu quero adicionar dimensões.

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

No primeiro exemplo, uso todos os elementos da primeira dimensão e adiciono uma segunda dimensão:

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

O segundo exemplo adiciona uma dimensão como primeira dimensão e, em seguida, usa todos os elementos da primeira dimensão da matriz original como elementos na segunda dimensão da 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)

Da mesma forma, você pode usar múltiplo np.newaxispara adicionar várias dimensões:

>>> 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)

Existem alternativas para np.newaxis?

Há outra funcionalidade muito semelhante no NumPy:, np.expand_dimsque também pode ser usada para inserir uma dimensão:

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

Mas, como ele apenas insere 1s no shapevocê, você também pode adicionar reshapeo array a essas dimensões:

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

Na maioria das vezes, np.newaxisé a maneira mais fácil de adicionar dimensões, mas é bom conhecer as alternativas.

Quando usar np.newaxis?

Em vários contextos está adicionando dimensões úteis:

  • Se os dados tiverem um número especificado de dimensões. Por exemplo, se você deseja usar matplotlib.pyplot.imshowpara exibir uma matriz 1D.

  • Se você deseja que o NumPy transmita matrizes. Ao adicionar uma dimensão que você poderia, por exemplo, obter a diferença entre todos os elementos de um array: a - a[:, np.newaxis]. Isso funciona porque as operações NumPy transmitem começando com a última dimensão 1 .

  • Para adicionar uma dimensão necessária para que o NumPy possa transmitir matrizes. Isso funciona porque cada dimensão de comprimento 1 é simplesmente transmitida para o comprimento da dimensão 1 correspondente da outra matriz.


1 Se você quiser ler mais sobre as regras de transmissão, a documentação do NumPy sobre esse assunto é muito boa. Também inclui um exemplo com 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
fonte
Não vejo a diferença entre o segundo e o terceiro casos de uso; ambos permitem permitir que o NumPy transmita uma matriz como parte de alguma operação. Caso contrário, ajudaria a adicionar um exemplo para o terceiro caso de uso, a fim de esclarecer o ponto.
Chiraz BenAbdelkader 01/07
@ChirazBenAbdelkader Sim, a distinção não é realmente tão distinta. Não tenho certeza se devo remover o terceiro ponto ou mesclá-lo ao segundo.
MSeifert 01/07
9

Você começou com uma lista unidimensional de números. Depois de usado numpy.newaxis, você o transformou em uma matriz bidimensional, consistindo em quatro linhas de uma coluna cada.

Você pode usar essa matriz para multiplicar a matriz ou envolvê-la na construção de uma matriz maior de 4 xn.

Kevin
fonte
5

newaxisO objeto na tupla de seleção serve para expandir as dimensões da seleção resultante por uma dimensão de unidade de comprimento .

Não é apenas a conversão da matriz de linhas em matriz de colunas.

Considere o exemplo abaixo:

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

Agora vamos adicionar nova dimensão aos nossos dados,

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

              [[4, 5, 6]],

              [[7, 8, 9]]])

Você pode ver que newaxisadicionou a dimensão extra aqui, x1 tinha dimensão (3,3) e X1_new tem dimensão (3,1,3).

Como nossa nova dimensão nos permite diferentes operações:

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

Adicionando x1_new e x2, obtemos:

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]]])

Portanto, newaxisnão é apenas a conversão da linha para a matriz da coluna. Aumenta a dimensão da matriz, permitindo assim fazer mais operações nela.

Hundiwala dura
fonte
1
Não é apenas matriz, funciona com qualquer ndarrayterminologia NumPy.
kmario23