Transpondo uma matriz NumPy


191

Eu uso Python e NumPy e tenho alguns problemas com "transpose":

import numpy as np
a = np.array([5,4])
print(a)
print(a.T)

Invocar a.Tnão está transpondo a matriz. Se afor, por exemplo [[],[]], ele transpõe corretamente, mas eu preciso da transposição de [...,...,...].


também tentei "imprimir a.transpose", que é o mesmo, mas sem sucesso, não transpõe ...
thaking

Respostas:


246

Está funcionando exatamente como deveria. A transposição de uma matriz 1D ainda é uma matriz 1D ! (Se você está acostumado ao matlab, ele basicamente não tem o conceito de uma matriz 1D. As matrizes "1D" do Matlab são 2D.)

Se você deseja transformar seu vetor 1D em uma matriz 2D e depois transpor, basta cortá-lo com np.newaxis(ou None, eles são iguais, newaxisé apenas mais legível).

import numpy as np
a = np.array([5,4])[np.newaxis]
print(a)
print(a.T)

De um modo geral, você não precisa se preocupar com isso. Adicionar a dimensão extra geralmente não é o que você deseja, se você está apenas fazendo isso por hábito. O Numpy transmitirá automaticamente uma matriz 1D ao fazer vários cálculos. Geralmente, não há necessidade de distinguir entre um vetor de linha e um vetor de coluna (nenhum dos quais são vetores . Ambos são 2D!) Quando você deseja apenas um vetor.


2
@ thhaking - Eu costumava np.arangefazer rapidamente uma matriz 1D. Funciona exatamente da mesma maneira para a = np.array([5,4]).
Joe Kington 10/10

2
Se você não conhece o numpy, lembre-se de que os colchetes ()não indicam uma dimensão adicional no numpy. Se a = np.arange(10)então aé array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])como produzido por a.__repr__(). Este é um a.ndim --> 1vetor unidimensional (ou seja ), conforme indicado entre colchetes []. O array( ... )não é visto quando você faz um print(a)ou outro a.__str__().
Dtlussier

7
@JoeKington, existe uma situação em que a transmissão de uma matriz 1D é útil. Calculando a distância entre todos os pontos 1D em uma matriz. Graças à sua solução de um pode fazer x - x [np.newaxis] .T que dá a matriz de distância
Juanpi

4
Pessoalmente, acho que np.vstack()a operação a ser mais explícito: print np.vstack(a).
Alexander Pozdneev

2
Não é apenas o matlab, mas a álgebra linear tem o conceito de um vetor de linha / coluna. Numpy é idiossincrático para pessoas vindas de vários lugares, não apenas para o Matlab.
21918 eric

133

Use dois pares de colchetes em vez de um. Isso cria uma matriz 2D, que pode ser transposta, ao contrário da matriz 1D criada se você usar um par de colchetes.

import numpy as np    
a = np.array([[5, 4]])
a.T

Exemplo mais completo:

>>> a = [3,6,9]
>>> b = np.array(a)
>>> b.T
array([3, 6, 9])         #Here it didn't transpose because 'a' is 1 dimensional
>>> b = np.array([a])
>>> b.T
array([[3],              #Here it did transpose because a is 2 dimensional
       [6],
       [9]])

Use o shapemétodo de numpy para ver o que está acontecendo aqui:

>>> b = np.array([10,20,30])
>>> b.shape
(3,)
>>> b = np.array([[10,20,30]])
>>> b.shape
(1, 3)

11
Eu prefiro essa solução à [np.newaxis], ela parece mais elegante.
PhilMacKay

Máquinas não são tão inteligentes. Mesmo se você tiver apenas uma esposa, ela deve ser declarada como sua primeira esposa.
Sreeragh AR

Esta deve ser a resposta escolhida
bruno

79

Para matrizes 1D :

a = np.array([1, 2, 3, 4])
a = a.reshape((-1, 1)) # <--- THIS IS IT

print a
array([[1],
       [2],
       [3],
       [4]])

Depois de entender que -1 aqui significa "quantas linhas forem necessárias", acho que essa é a maneira mais legível de "transpor" uma matriz. Se sua matriz é de maior dimensionalidade, basta usar a.T.


5
Observe que isso funciona apenas com vetores. Se você tiver uma matriz bidimensional, as operações transposee reshapemodificam a matriz de maneiras diferentes (a forma da imagem resultante é a mesma, mas os elementos são colocados de maneira diferente).
Johndodo

2
Obrigado pela sua observação. Entendo seu ponto de vista, mas acho que isso distrai mais do que esclarece minha resposta, porque dou uma solução simples de uma linha para a pergunta exata que o @thaking enquadra. Não se trata de matrizes 2-d, trata-se de matrizes 1-d. Maçãs e peras aqui.
precisa saber é o seguinte

2
Claro. Sua resposta é correta e elegante para este caso, nunca pretendi criticá-lo. Mas, considerando o título da pergunta ("Transpondo um array NumPy"), suspeito que muitos visitantes venham aqui procurando uma solução mais genérica e gostaria de avisá-los de que não é aplicável a matrizes 2D. Caso contrário, sua resposta está correta e adequada, dada a pergunta do OP.
Johndodo 7/03

@UlfAslak, atualize sua resposta de que sua abordagem não é generalizável para o array ND, é sempre bom esclarecer antecipadamente, como sugerido por! Johndodo, para que ninguém use sua técnica incorretamente. !, a pergunta aqui é a resposta certa e não um forro.!
Anu

18

Você pode converter um vetor existente em uma matriz envolvendo-o em um conjunto extra de colchetes ...

from numpy import *
v=array([5,4]) ## create a numpy vector
array([v]).T ## transpose a vector into a matrix

numpy também tem uma matrixclasse (veja matriz vs. matriz ) ...

matrix(v).T ## transpose a vector into a matrix

14

matriz 1D numpy -> matriz de colunas / linhas:

>>> a=np.array([1,2,4])
>>> a[:, None]    # col
array([[1],
       [2],
       [4]])
>>> a[None, :]    # row, or faster `a[None]`
array([[1, 2, 4]])

E como @ joe-kington disse, você pode substituir Nonecom np.newaxispara facilitar a leitura.


10

Para 'transpor' uma matriz 1d para uma coluna 2d, você pode usar numpy.vstack:

>>> numpy.vstack(numpy.array([1,2,3]))
array([[1],
       [2],
       [3]])

Também funciona para listas de baunilha:

>>> numpy.vstack([1,2,3])
array([[1],
       [2],
       [3]])

1
@sandroscodelller, você olhou o código subjacente vstack? np.concatenate([atleast_2d(_m) for _m in tup], 0). Ele divide a matriz em (1,1) matrizes e concatena essas! No processo, ele faz uma cópia, enquanto todos os que estão remodelados fazem uma visualização.
hpaulj

3

Você só pode transpor uma matriz 2D. Você pode usar numpy.matrixpara criar uma matriz 2D. Isso está atrasado três anos, mas estou apenas adicionando ao possível conjunto de soluções:

import numpy as np
m = np.matrix([2, 3])
m.T

O uso de np.matrixnão é necessário e geralmente está sendo desencorajado.
hpaulj



2

Outra solução .... :-)

import numpy as np

a = [1,2,4]

[1, 2, 4]

b = np.array([a]).T

matriz ([[1], [2], [4]])


Qual é o problema com esta solução ?!
Omotto 26/10

1

Estou apenas consolidando o post acima, espero que ajude outras pessoas a economizar algum tempo:

A matriz abaixo tem (2, )dimensão, é uma matriz 1-D,

b_new = np.array([2j, 3j])  

Há duas maneiras de transpor uma matriz 1-D:


corte-o com "np.newaxis" ou nenhum.

print(b_new[np.newaxis].T.shape)
print(b_new[None].T.shape)

outra maneira de escrever, o acima sem Toperação.!

print(b_new[:, np.newaxis].shape)
print(b_new[:, None].shape)

Agrupar [] ou usar np.matrix significa adicionar uma nova dimensão.

print(np.array([b_new]).T.shape)
print(np.matrix(b_new).T.shape)

0

Como alguns dos comentários acima mencionados, a transposição de matrizes 1D são matrizes 1D, portanto, uma maneira de transpor uma matriz 1D seria converter a matriz em uma matriz da seguinte forma:

np.transpose(a.reshape(len(a), 1))


0

Existe um método não descrito nas respostas, mas descrito na documentação para o numpy.ndarray.transposemétodo:

Para uma matriz 1-D, isso não tem efeito, pois um vetor transposto é simplesmente o mesmo vetor. Para converter uma matriz 1-D em um vetor de coluna 2D, uma dimensão adicional deve ser adicionada. np.atleast2d (a) .T consegue isso, assim como uma [:, np.newaxis].

Pode-se fazer:

import numpy as np
a = np.array([5,4])
print(a)
print(np.atleast_2d(a).T)

Qual (imo) é melhor do que usar newaxis.


0

Basicamente, o que a função de transposição faz é trocar a forma e os passos da matriz:

>>> a = np.ones((1,2,3))

>>> a.shape
(1, 2, 3)

>>> a.T.shape
(3, 2, 1)

>>> a.strides
(48, 24, 8)

>>> a.T.strides
(8, 24, 48)

No caso de um array numpy 1D (array 1), a forma e os passos são tuplas de 1 elemento e não podem ser trocados, e a transposição de um array 1D retorna-o inalterado. Em vez disso, você pode transpor um "vetor de linha" (matriz numpy de forma (1, n)) para um "vetor de coluna" (matriz numpy de forma (n, 1)). Para conseguir isso, você deve primeiro converter sua matriz numpy 1D em vetor de linha e depois trocar a forma e as passadas (transpor). Abaixo está uma função que faz isso:

from numpy.lib.stride_tricks import as_strided

def transpose(a):
    a = np.atleast_2d(a)
    return as_strided(a, shape=a.shape[::-1], strides=a.strides[::-1])

Exemplo:

>>> a = np.arange(3)
>>> a
array([0, 1, 2])

>>> transpose(a)
array([[0],
       [1],
       [2]])

>>> a = np.arange(1, 7).reshape(2,3)
>>> a     
array([[1, 2, 3],
       [4, 5, 6]])

>>> transpose(a)
array([[1, 4],
       [2, 5],
       [3, 6]])

É claro que você não precisa fazer isso dessa maneira, já que possui uma matriz 1D e pode remodelá-la diretamente na (n, 1)matriz por a.reshape((-1, 1))ou a[:, None]. Eu só queria demonstrar como a transposição de uma matriz funciona.


0

A maneira como aprendi a implementar isso de maneira compacta e legível para matrizes 1-D, até agora:

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

v1 = np.vstack(h)
v2 = np.c_[h]

h1 = np.hstack(v1)
h2 = np.r_[v2[:,0]]

numpy.r_ e numpy.c_ convertem objetos de fatia em concatenação ao longo do primeiro e do segundo eixo, respectivamente. Portanto, o fatiamento v2 [: 0] na transposição de volta da matriz vertical v2 para a matriz horizontal h2

numpy.vstack é equivalente à concatenação ao longo do primeiro eixo depois que as matrizes 1-D da forma (N) foram remodeladas para (1, N). Recria matrizes divididas por vsplit .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.