2010-11-11 14 views
245

Jakie są zalety i wady każdego z nich?Jakie są różnice pomiędzy numpy macierzami i macierzami? Którego powinienem użyć?

Z tego, co widziałem, każdy może pracować jako zamiennik dla drugiego, jeśli trzeba, więc powinienem zawracać sobie głowę użyciem obu lub powinienem trzymać się tylko jednego z nich?

Czy styl programu wpłynie na mój wybór? Robię pewne uczenie maszynowe za pomocą numpy, więc w rzeczywistości istnieje wiele matryc, ale także wiele wektorów (tablic).

+2

Nie mam wystarczających informacji, aby uzasadnić odpowiedź, ale z tego, co mogę powiedzieć, główna różnica polega na wdrożeniu mnożenia. Macierz wykonuje mnożenie macierzy/tensora, podczas gdy tablica dokonuje mnożenia elementarnego. –

+2

Python 3.5 dodał operator infix @ do mnożenia macierzy (PEP 465), a NumPy 1.10 dodał obsługę. Więc jeśli używasz Pythona 3.5+ i NumPy 1.10+, możesz po prostu napisać 'A @ B' zamiast' A.dot (B) ', gdzie' A' i 'B' są 2D' ndarray's. To eliminuje główną zaletę używania 'matrix' zamiast zwykłego' ndarray's, IMHO. – MiniQuark

Odpowiedz

283

Macierze Numpy są ściśle 2-wymiarowe, natomiast numpy tablice (ndarrays) są N-wymiarowe. Obiekty macierzy są podklasą ndarray, więc dziedziczą wszystkie atrybuty i metody ndarrays.

Główną zaletą numpy matryc jest to, że zapewniają wygodną notację dla mnożenia macierzy: jeśli a i b są macierzami, to a * b jest ich macierzą produkt.

import numpy as np 

a=np.mat('4 3; 2 1') 
b=np.mat('1 2; 3 4') 
print(a) 
# [[4 3] 
# [2 1]] 
print(b) 
# [[1 2] 
# [3 4]] 
print(a*b) 
# [[13 20] 
# [ 5 8]] 

Z drugiej strony, jak Pythona 3.5, NumPy obsługuje Infix mnożenia macierzy za pomocą operatora @, dzięki czemu można osiągnąć taką samą wygodę mnożenia macierzy z ndarrays w Pythonie> = 3.5.

import numpy as np 

a=np.array([[4, 3], [2, 1]]) 
b=np.array([[1, 2], [3, 4]]) 
print([email protected]) 
# [[13 20] 
# [ 5 8]] 

Oba obiekty matrycy i ndarrays mają .T powrotu transpozycję, ale macierz przedmiotów także .H przez sprzężoną transpozycję i .I na odwrotnym.

W przeciwieństwie do tablic numpy konsekwentnie stosuje się zasadę, że operacje są stosowane elementycznie (z wyjątkiem nowego operatora @). Tak więc, jeśli a i b są NumPy tablice następnie a*b jest tablica utworzony przez mnożenie elementów element mądry:

c=np.array([[4, 3], [2, 1]]) 
d=np.array([[1, 2], [3, 4]]) 
print(c*d) 
# [[4 6] 
# [6 4]] 

Aby uzyskać wynik mnożenia macierzy można użyć np.dot (lub @ Pythona> = 3.5, jak to przedstawiono powyżej)

print(np.dot(c,d)) 
# [[13 20] 
# [ 5 8]] 

operator ** zachowuje także w inny sposób:

print(a**2) 
# [[22 15] 
# [10 7]] 
print(c**2) 
# [[16 9] 
# [ 4 1]] 

Ponieważ a jest macierzą, a**2 zwraca produkt macierzowy a*a. Od c jest ndarray, c**2 zwraca ndarray z każdym elementem do kwadratu elementowo.

Istnieją inne techniczne różnice między obiektami macierzowymi i ndarrays (związane z np.ravel, wyborem pozycji i zachowaniem sekwencji).

Główną zaletą tablic numpy jest to, że są one bardziej ogólne niż macierze 2-wymiarowe o rozmiarach od . Co się dzieje, gdy chcesz 3-wymiarowej tablicy? Następnie musisz użyć ndarray, a nie obiektu macierzy.W związku z tym uczenie się korzystania z obiektów macierzowych wymaga więcej pracy - musisz nauczyć się operacji na macierzy i operacji na tablicach.

Pisanie programu, który używa zarówno macierzy jak i tablic, utrudnia życie , ponieważ trzeba śledzić, jaki typ obiektu są twoje zmienne, aby mnożenie nie powróciło, czego nie oczekujesz.

W przeciwieństwie do tego, jeśli pozostaniesz tylko przy użyciu ndarrays, możesz zrobić wszystko, co można zrobić z obiektami macierzowymi, i więcej, z wyjątkiem nieco innych funkcji/notacji .

Jeśli chcesz zrezygnować z atrakcyjności notacji NumPy matrix (co można osiągnąć równie elegancko z ndarrays w Pythonie> = 3.5), to sądzę, że tablice NumPy są zdecydowanie drogą do zrobienia.

PS. Oczywiście, naprawdę nie musisz wybierać jednego kosztem drugiego, od np.asmatrix i np.asarray pozwala na konwersję jednego do drugiego (jako długo, jak tablica jest dwuwymiarowa).


Jest streszczenie różnic między NumPy arrays vs NumPy matrix ES here.

+5

Dla tych, którzy się zastanawiają, 'mat ** n' dla macierzy może być nieelegancko zastosowane do tablicy z' reduce (np.dot, [arr] * n) ' – askewchan

+2

Lub po prostu' np.linalg.matrix_power (mat, n) ' – Eric

+0

Zastanawiam się, czy macierze byłyby szybsze ... mogłoby się wydawać, że muszą wykonywać mniej sprawdzeń niż ndarray. – PascalVKooten

23

Wystarczy, aby dodać jedną sprawę do listy unutbu.

Jedną z największych praktycznych różnic dla mnie dla numpy ndarray w porównaniu do numpy matryc lub języków macierzy takich jak Matlab, jest to, że wymiar nie jest zachowywany w operacjach redukcji. Matryce są zawsze 2d, podczas gdy średnia z tablicy, na przykład, ma jeden wymiar mniej.

Przykładowo demean wierszy macierzy lub tablicy:

z matrycy

>>> m = np.mat([[1,2],[2,3]]) 
>>> m 
matrix([[1, 2], 
     [2, 3]]) 
>>> mm = m.mean(1) 
>>> mm 
matrix([[ 1.5], 
     [ 2.5]]) 
>>> mm.shape 
(2, 1) 
>>> m - mm 
matrix([[-0.5, 0.5], 
     [-0.5, 0.5]]) 

z tablicy

>>> a = np.array([[1,2],[2,3]]) 
>>> a 
array([[1, 2], 
     [2, 3]]) 
>>> am = a.mean(1) 
>>> am.shape 
(2,) 
>>> am 
array([ 1.5, 2.5]) 
>>> a - am #wrong 
array([[-0.5, -0.5], 
     [ 0.5, 0.5]]) 
>>> a - am[:, np.newaxis] #right 
array([[-0.5, 0.5], 
     [-0.5, 0.5]]) 

I również, że mieszanie tablic i macierzy prowadzi do wielu „Happy "godziny debugowania. Jednak macierze scipy.sparse są zawsze macierzami pod względem operatorów takich jak mnożenie.

69

Scipy.org recommends that you use arrays:

* 'tablica' i 'matryca'? Którego powinienem użyć? - Krótka odpowiedź:

Użyj tablic.

  • Są standardowym typem wektora/macierzy/tensora numpy. Wiele macierzowych funkcji zwracających tablice, a nie matryce.

  • Istnieje wyraźne rozróżnienie między operacjami elementarnymi i operacjami algebry liniowej .

  • Możesz mieć standardowe wektory lub wektory wiersz/kolumna, jeśli chcesz.

Jedyną wadą stosowania rodzaj tablicy, że trzeba będzie stosowania dot zamiast * pomnożyć (zmniejszenie) dwóch tensory (produkt skalarne matrycy mnożenie wektorowe itd.).

+6

Nawet jeśli zaakceptowana odpowiedź dostarcza więcej informacji, prawdziwą odpowiedzią jest rzeczywiście trzymanie się 'ndarray'. Głównym argumentem za używaniem 'matrix' byłoby, gdyby twój kod był ciężki w algebrze liniowej i wyglądałby mniej wyraźnie przy wszystkich wywołaniach funkcji" kropka ". Ale ten argument zniknie w przyszłości, teraz, gdy @ -operator jest akceptowany do użytku z mnożeniem macierzy, patrz [PEP 465] (https://www.python.org/dev/peps/pep-0465/). Będzie to wymagało Pythona 3.5 i najnowszej wersji Numpy. Klasa macierzy może być przestarzała w dalekiej przyszłości, więc lepiej użyć ndarray dla nowego kodu ... –

+4

Strona ta łaskawie zapomina o macierzy 'scipy.sparse'. Jeśli użyjesz zarówno gęstych, jak i rzadkich macierzy w kodzie, znacznie łatwiej będzie trzymać się "matrycy". –

+1

Moim zdaniem, główną wadą tablic jest to, że przecinanie kolumn zwraca płaskie tablice, które mogą być mylące i matematycznie niezbyt dobre. Prowadzi to również do istotnej wady polegającej na tym, że numpy macierze nie mogą być traktowane w taki sam sposób jak matryce scipy.sparse, podczas gdy numpy macierze mogą być w zasadzie swobodnie wymieniane z rzadkimi matrycami. W tym kontekście absurd, który scipy zaleca używanie tablic, a następnie nie zapewnia kompatybilnych, rzadkich tablic. –

Powiązane problemy