Transponowanie tablicy NumPy

193

Używam Python i NumPy i mam pewne problemy z „transponowaniem”:

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

Wywołanie a.Tnie transponuje tablicy. Jeśli ajest na przykład, [[],[]]to transponuje się poprawnie, ale potrzebuję transpozycji [...,...,...].

thaking
źródło
Próbowałem również „print a.transpose”, która jest taka sama, ale bez sucess, nie transpozycji ...
thaking

Odpowiedzi:

247

Działa dokładnie tak, jak powinien. Transpozycja macierzy 1D jest nadal macierzą 1D ! (Jeśli jesteś przyzwyczajony do Matlaba, zasadniczo nie ma pojęcia tablicy 1D. Tablice Matlaba „1D” są 2D.)

Jeśli chcesz przekształcić wektor 1D w macierz 2D, a następnie transponować go, po prostu pokrój go np.newaxis(lub None, tak samo, newaxisjest po prostu bardziej czytelny).

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

Ogólnie rzecz biorąc, nigdy nie musisz się o to martwić. Dodanie dodatkowego wymiaru zwykle nie jest tym, czego chcesz, jeśli robisz to z przyzwyczajenia. Numpy automatycznie wyemituje tablicę 1D podczas wykonywania różnych obliczeń. Tam zazwyczaj nie ma potrzeby rozróżniania pomiędzy wektorem wiersza i kolumny wektor (z których żaden nie są wektory . Są zarówno 2D!), Gdy chcesz po prostu wektor.

Joe Kington
źródło
2
@ thaking - Właśnie użyłem, np.arangeaby szybko zrobić tablicę 1D. Działa dokładnie tak samo dla a = np.array([5,4]).
Joe Kington,
2
@thaking Jeśli jesteś nowy w numpy - pamiętaj, że okrągłe nawiasy ()nie wskazują dodatkowego wymiaru w numpy. Jeśli a = np.arange(10)tak, ato array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])jak wyprodukował a.__repr__(). Jest to a.ndim --> 1wektor 1-wymiarowy (tj. ), Jak wskazano w nawiasach kwadratowych []. array( ... )Nie jest widoczne, gdy robisz albo print(a)albo a.__str__().
dtlussier
7
@JoeKington zdarza się sytuacja, że ​​nadawanie tablicy 1D jest przydatne. Obliczanie odległości między wszystkimi punktami 1D w tablicy. Dzięki swojemu rozwiązaniu można wykonać x - x [np.newaxis] .T, co daje macierz odległości
JuanPi
4
Osobiście uważam, że np.vstack()operacja się być bardziej wyraźne: print np.vstack(a).
Alexander Pozdneev
2
To nie tylko matlab, ale algebra liniowa ma pojęcie wektora wiersza / kolumny. Numpy jest charakterystyczne dla ludzi pochodzących z wielu miejsc, nie tylko z Matlaba.
eryczny
135

Użyj dwóch par wsporników zamiast jednej. Tworzy to tablicę 2D, którą można transponować, w przeciwieństwie do tablicy 1D, którą tworzysz, jeśli używasz jednej pary wsporników.

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

Bardziej dokładny przykład:

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

Użyj shapemetody numpy, aby zobaczyć, co się tutaj dzieje:

>>> b = np.array([10,20,30])
>>> b.shape
(3,)
>>> b = np.array([[10,20,30]])
>>> b.shape
(1, 3)
dziki
źródło
11
Wolę to rozwiązanie od [np.newaxis], wygląda bardziej elegancko imo.
PhilMacKay
Maszyny nie są tak inteligentne. Nawet jeśli masz tylko jedną żonę, powinna zostać zadeklarowana jako Twoja pierwsza żona.
Sreeragh AR
To powinna być wybrana odpowiedź
bruno
79

Dla tablic 1D :

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

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

Kiedy zrozumiesz, że -1 oznacza tutaj „tyle wierszy, ile potrzeba”, uważam, że jest to najbardziej czytelny sposób na „transponowanie” tablicy. Jeśli twoja tablica ma wyższą wymiarowość, po prostu użyj a.T.

Ulf Aslak
źródło
5
Zauważ, że działa to tylko z wektorami. Jeśli masz tablicę dwuwymiarową, operacje transposei reshapemodyfikuj tablicę na różne sposoby (wynikowy kształt obrazu jest taki sam, ale elementy są rozmieszczone inaczej).
johndodo
2
Dziękuję za twoją uwagę. Rozumiem twój punkt widzenia, ale myślę, że bardziej odwraca uwagę niż wyjaśnia moją odpowiedź, ponieważ daję proste, jednowierszowe rozwiązanie dokładnie pytania, które @takie ramki. Nie chodzi o tablice 2-d, chodzi o tablice 1-d. Jabłka i gruszki tutaj.
Ulf Aslak
2
Oczywiście. Twoja odpowiedź jest poprawna i elegancka w tej sprawie, nigdy nie chciałem jej krytykować. Ale biorąc pod uwagę tytuł pytania („Transpozycja tablicy NumPy”), podejrzewam, że wielu odwiedzających przyjdzie tutaj w poszukiwaniu bardziej ogólnego rozwiązania i chciałem ich ostrzec, że nie dotyczy to tablic 2D. W przeciwnym razie Twoja odpowiedź jest poprawna i odpowiednia, biorąc pod uwagę pytanie PO.
johndodo
@UlfAslak, proszę zaktualizuj swoją odpowiedź, że twoje podejście nie jest możliwe do uogólnienia na macierz ND, zawsze dobrze jest być wyraźnie z góry, jak sugeruje! Johndodo, aby nikt nie powinien niewłaściwie używać twojej techniki.!, Pytanie tutaj jest dla właściwej odpowiedzi a nie wkładka.!
Anu,
18

Możesz przekonwertować istniejący wektor na macierz, zawijając go w dodatkowy zestaw nawiasów kwadratowych ...

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

numpy ma również matrixklasę (patrz tablica vs. macierz ) ...

matrix(v).T ## transpose a vector into a matrix
Brent Bradburn
źródło
14

tablica numpy 1D -> macierz kolumn / wierszy:

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

I jak @ joe-kington powiedział, można wymienić Noneze np.newaxisdla czytelności.

ankostis
źródło
10

Aby „przetransponować” tablicę 1d do kolumny 2d, możesz użyć numpy.vstack:

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

Działa również w przypadku list waniliowych:

>>> numpy.vstack([1,2,3])
array([[1],
       [2],
       [3]])
Pułkownik Panika
źródło
1
@ sandrosodelller, czy obejrzałeś kod leżący u jego podstaw vstack? np.concatenate([atleast_2d(_m) for _m in tup], 0). Dzieli tablicę na tablice (1,1) i łączy je! Podczas tego procesu tworzy kopię, podczas gdy wszystkie przekształcone tworzą widok.
hpaulj
3

Możesz transponować tylko tablicę 2D. Możesz użyć numpy.matrixdo utworzenia tablicy 2D. Spóźnia się o trzy lata, ale dodajemy tylko do możliwego zestawu rozwiązań:

import numpy as np
m = np.matrix([2, 3])
m.T
Jean-Louis Mbaka
źródło
Używanie np.matrixnie jest potrzebne i ogólnie jest odradzane.
hpaulj
3

zamiast tego użyj arr[:,None]do utworzenia wektora kolumny

Mohammed Awney
źródło
2

Inne rozwiązanie.... :-)

import numpy as np

a = [1,2,4]

[1, 2, 4]

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

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

omotto
źródło
Jaki jest problem z tym rozwiązaniem ?!
omotto
1

Właśnie konsoliduję powyższy post, mam nadzieję, że pomoże innym zaoszczędzić trochę czasu:

Poniższa tablica ma (2, )wymiar, jest to tablica 1-D,

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

Istnieją dwa sposoby transpozycji tablicy 1-D:


pokroić na „np.newaxis” lub brak.!

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

inny sposób pisania, powyższe bez Toperacji.!

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

Zawijanie [] lub użycie np.matrix oznacza dodanie nowego wymiaru.!

print(np.array([b_new]).T.shape)
print(np.matrix(b_new).T.shape)
Anu
źródło
0

Jak niektóre z wyżej wspomnianych komentarzy, transpozycja tablic 1D to tablice 1D, więc jednym ze sposobów transpozycji tablicy 1D byłoby przekonwertowanie tablicy na macierz w następujący sposób:

np.transpose(a.reshape(len(a), 1))
TheOriginalAlex
źródło
0

Nazwa funkcji w numpyto column_stack .

>>>a=np.array([5,4])
>>>np.column_stack(a)
array([[5, 4]])
tmarthal
źródło
0

Jest to metoda nie została opisana w odpowiedzi, ale opisane w dokumentacji dla numpy.ndarray.transposemetody:

W przypadku tablicy 1-D nie ma to żadnego efektu, ponieważ transponowany wektor jest po prostu tym samym wektorem. Aby przekonwertować tablicę 1-D na wektor kolumny 2D, należy dodać dodatkowy wymiar. np.atleast2d (a) .T osiąga to, podobnie jak [:, np.newaxis].

Można zrobić:

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

Które (imo) jest ładniejsze niż używanie newaxis.

Amin Karbas
źródło
0

Zasadniczo funkcja transpozycji polega na zamianie kształtu i kroków tablicy:

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

W przypadku tablicy numpy 1D (tablica rangi 1) kształt i kroki są krotkami 1-elementowymi i nie można ich zamienić, a transpozycja takiej tablicy 1D zwraca ją bez zmian. Zamiast tego możesz przetransponować „wektor wiersza” (tablica numeryczna kształtu (1, n)) na „wektor kolumnowy” (tablica numeryczna kształtu (n, 1)). Aby to osiągnąć, musisz najpierw przekonwertować tablicę numpy 1D na wektor wiersza, a następnie zamienić kształt i kroki (przetransponować). Poniżej znajduje się funkcja, która to robi:

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

Przykład:

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

Oczywiście nie musisz tego robić w ten sposób, ponieważ masz tablicę 1D i możesz bezpośrednio przekształcić ją w (n, 1)tablicę za pomocą a.reshape((-1, 1))lub a[:, None]. Chciałem tylko pokazać, jak działa transpozycja macierzy.

Andreas K.
źródło
0

Sposób, w jaki nauczyłem się implementować to w zwarty i czytelny sposób dla tablic 1-D, jak dotąd:

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_ i numpy.c_ tłumaczą obiekty plasterków na konkatenację odpowiednio wzdłuż pierwszej i drugiej osi. Dlatego krojenie v2 [:, 0] w transponowaniu z powrotem pionowej tablicy v2 do poziomej tablicy h2

numpy.vstack jest równoważne konkatenacji wzdłuż pierwszej osi po przekształceniu tablic kształtu 1-D (N,) w (1, N). Odbudowuje tablice podzielone przez vsplit .

i śpiewał
źródło