Numpy dizileri ve matrisler arasındaki farklar nelerdir? Hangisini kullanmalıyım?


346

Her birinin avantajları ve dezavantajları nelerdir?

Gördüğüm kadarıyla, ya biri gerekirse diğerinin yerine çalışabilir, bu yüzden her ikisini de kullanmalı mıyım yoksa bunlardan birine mi yapışmalıyım?

Programın tarzı seçimimi etkiler mi? Ben numpy kullanarak bazı makine öğrenme yapıyorum, bu yüzden gerçekten çok matris, ama aynı zamanda çok sayıda vektör (diziler) vardır.


3
Bir cevabı haklı çıkarmak için yeterli bilgiye sahip değilim, ancak ana farkı söyleyebileceğim çarpma işlemidir. Bir matris matris / tensör çarpımını gerçekleştirirken, bir dizi eleman bazında çarpım yapar.
Mike Axiak

5
Python 3.5, matris çarpımı için infix @ operatörünü ekledi (PEP 465) ve NumPy 1.10 buna destek ekledi. Yani Python 3.5+ ve NumPy 1.10+ kullanıyorsanız, 2D s A @ Byerine A.dot(B)nerede Ave yazabilirsiniz . Bu , düz s yerine IMHO kullanmanın ana avantajını ortadan kaldırır . Bndarraymatrixndarray
MiniQuark

Yanıtlar:



396

Numpy matrisleri kesinlikle 2 boyutlu iken numpy dizileri (ndarrays) N-boyutludur. Matris nesneleri bir ndarray alt sınıfıdır, bu nedenle ndarrayların tüm niteliklerini ve yöntemlerini devralırlar.

Numpy matrislerin ana avantajı, matris çarpımı için uygun bir gösterim sağlamalarıdır: a ve b matris a*bise, matris ürünüdür.

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

Öte yandan, Python 3.5'ten itibaren, NumPy @operatörü kullanarak infix matris çarpımını destekler , böylece Python> = 3.5'de ndarraylarla aynı matris çarpma rahatlığını elde edebilirsiniz.

import numpy as np

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

Hem matris nesneleri hem de ndarray'ların .Taktarımı döndürmesi gerekir, ancak matris nesnelerinin de .Hkonjugat aktarımı için olması gerekir ve.I tersi için de vardır.

Buna karşılık, numpy dizileri, işlemlerin eleman olarak uygulandığı kuralına (yeni @operatör hariç ) tutarlı bir şekilde uyar . Böylece, ave bnumpy diziler, o zaman a*böğeye bileşenleri çarpılmasıyla oluşturulan dizidir:

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

Matris çarpımının sonucunu elde etmek için kullanın np.dot(veya @yukarıda gösterildiği gibi Python> = 3.5'te):

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

**Operatör aynı zamanda farklı davranır:

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

Bu yana abir matris, a**2matris ürün verir a*a. Bu yana cbir ndarray olup, c**2her bir bileşen kare öğeye sahip bir ndarray döndürür.

Matris nesneleri ve ndarrays arasında başka teknik farklılıklar da vardır ( np.ravelöğe seçimi ve sıra davranışı ile ilgili).

Numpy dizilerin ana avantajı, 2 boyutlu matrislerden daha genel olmalarıdır . 3 boyutlu bir dizi istediğinizde ne olur? O zaman bir matris nesnesi değil, bir ndarray kullanmalısınız. Bu nedenle, matris nesnelerini kullanmayı öğrenmek daha fazla iştir - matris nesne işlemlerini ve ndarray işlemlerini öğrenmeniz gerekir.

Hem matrisleri hem de dizileri karıştıran bir program yazmak hayatınızı zorlaştırır, çünkü değişkenlerinizin ne tür bir nesne olduğunu takip etmek zorunda kalırsanız, çarpma beklemediğiniz bir şeyi döndürür.

Buna karşılık, sadece ndarrays ile yapışırsanız, matris nesnelerinin yapabileceği her şeyi ve daha fazlasını yapabilirsiniz, ancak biraz farklı işlevler / gösterimler hariç.

NumPy matris ürün notasyonunun görsel cazibesinden vazgeçmek istiyorsanız (Python> = 3.5'teki ndarraylarla neredeyse zarif bir şekilde elde edilebilir), o zaman NumPy dizilerinin kesinlikle gitmenin yolu olduğunu düşünüyorum.

PS. Tabii ki, gerçekten diğerinin pahasına birini seçmek zorunda değilsiniz, çünkü np.asmatrixve diğerini np.asarraydönüştürmenize izin verir (dizi 2 boyutlu olduğu sürece).


Numpy arasındaki farkların bir özeti vardır arraysNumPy vs matrixes burada .


7
Merak edenler mat**niçin, bir matris için bir diziye reduce(np.dot, [arr]*n)
yetersiz

6
Veya sadecenp.linalg.matrix_power(mat, n)
Eric

Matrislerin daha hızlı olup olmayacağını merak ediyorum ... ndarray'dan daha az kontrol yapmaları gerektiğini düşünürdünüz.
PascalVKooten

1
Aslında timeit testleri ndarray işlemlerini np.dot(array2, array2)daha hızlı gösterir matrix1*matrix2. Bu mantıklıdır, çünkü matrixözel yöntemleri geçersiz kılan bir ndarray alt sınıfıdır __mul__. matrix.__mul__çağrılarınp.dot . Burada kod yeniden kullanımı var. Daha az kontrol yapmak yerine, kullanmak matrix*matrixiçin ekstra işlev çağrısı gerekir. Bu yüzden kullanmanın avantajı matrixdaha iyi performans değil, tamamen sözdizimseldir.
unutbu

4 * 1 + 3 * 3 np.dot (c, d) yaptığınızda size 13 verir, bu aslında matematikte çapraz ürün olarak adlandırılmaz
PirateApp

92

Scipy.org dizileri kullanmanızı önerir:

* 'dizi' veya 'matris'? Hangisini kullanmalıyım? - Kısa cevap

Diziler kullanın.

  • Bunlar standart vektör / matris / tensör türü numpy'dir. Birçok numpy işlevi, matrisleri değil, dizileri döndürür.

  • Elemanlar ve lineer cebir işlemleri arasında açık bir ayrım vardır.

  • İsterseniz standart vektörlere veya satır / sütun vektörlerine sahip olabilirsiniz.

Dizi türünü kullanmanın tek dezavantajı, iki tensörü (skaler ürün, matris vektör çarpımı vb.) Çarpmak (azaltmak) dotyerine kullanmak zorunda olmanızdır *.


11
Kabul edilen cevap daha fazla bilgi sağlamasına rağmen, asıl cevap gerçekten sadık kalmaktır ndarray. Kullanmanın ana argümanı matrix, kodunuzun lineer cebirde ağır olması ve dotişleve yapılan tüm çağrılarda daha az net görünmesi olacaktır . Ancak bu argüman gelecekte kaybolacaktır, artık @ -operator matris çarpımı ile kullanım için kabul edilmektedir, bkz. PEP 465 . Bunun için Python 3.5 ve Numpy'nin en son sürümü gerekecektir. Matris sınıfı uzak gelecekte kaldırılabilir, bu yüzden yeni kod için ndarray kullanmak daha iyi ...
Bas Swinckels

6
Bu sayfa nezaketle scipy.sparsematrisleri unutuyor . Kodunuzda hem yoğun hem de seyrek matrisler kullanırsanız, yapışmanız çok daha kolaydır matrix.
David Nemeskey

3
Bence, dizilerin ana dezavantajı, sütun dilimlemenin kafa karıştırıcı olabilen ve matematiksel olarak gerçekten sağlam olmayan düz diziler döndürmesidir. Bu aynı zamanda numpy dizilerinin scipy ile aynı şekilde tedavi edilememesi gibi önemli bir dezavantaja yol açar. Bu bağlamda, scipy dizileri kullanmanızı tavsiye eder ve daha sonra uyumlu seyrek diziler sağlamaz.
Radyo Kontrollü

29

Sadece unutbu'nun listesine bir dava eklemek için.

Numpy ndarrays benim için numpy matrisleri veya matlab gibi matris dilleri ile karşılaştırıldığında en büyük pratik farklılıklardan biri, boyutun küçültme işlemlerinde korunmamasıdır. Matrisler her zaman 2d'dir, örneğin bir dizinin ortalamasının bir boyutu daha azdır.

Örneğin, bir matris veya dizinin demean satırları:

matris ile

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

dizi ile

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

Ayrıca dizileri ve matrisleri karıştırmanın birçok "mutlu" hata ayıklama saatine yol açtığını düşünüyorum. Ancak, scipy.sparse matrisleri her zaman çarpma gibi operatörler açısından matrislerdir.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.