Apa perbedaan antara array numpy dan matriks? Yang mana yang harus saya gunakan?

345

Apa kelebihan dan kekurangan masing-masing?

Dari apa yang saya lihat, salah satu dapat berfungsi sebagai pengganti yang lain jika perlu, jadi haruskah saya repot menggunakan keduanya atau haruskah saya tetap berpegang pada salah satu saja?

Apakah gaya program mempengaruhi pilihan saya? Saya melakukan beberapa pembelajaran mesin menggunakan numpy, jadi memang ada banyak matriks, tetapi juga banyak vektor (array).

levesque
sumber
3
Saya tidak memiliki informasi yang cukup untuk membenarkan jawaban tetapi dari apa yang dapat saya katakan perbedaan utamanya adalah penerapan perkalian. Matriks melakukan perkalian matriks / tensor, sedangkan array akan melakukan perkalian elemen-bijaksana.
Mike Axiak
5
Python 3.5 menambahkan operator infix @ untuk perkalian matriks (PEP 465), dan NumPy 1.10 menambahkan dukungan untuk itu. Jadi jika Anda menggunakan Python 3.5+ dan NumPy 1.10+, maka Anda bisa menulis A @ Balih-alih A.dot(B), di mana Adan B2D ndarrays. Ini menghilangkan keuntungan utama menggunakan matrixbukan ndarrays polos , IMHO.
MiniQuark

Jawaban:

396

Matriks numpy benar-benar 2 dimensi, sedangkan numpy array (ndarrays) adalah N-dimensional. Objek matriks adalah subkelas dari ndarray, sehingga mereka mewarisi semua atribut dan metode ndarray.

Keuntungan utama dari matriks numpy adalah bahwa mereka memberikan notasi yang nyaman untuk perkalian matriks: jika a dan b adalah matriks, maka a*badalah produk matriks mereka.

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

Di sisi lain, pada Python 3.5, NumPy mendukung perkalian matriks infiks menggunakan @operator, sehingga Anda dapat mencapai kenyamanan yang sama dari perkalian matriks dengan ndarrays di Python> = 3.5.

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

Objek matriks dan ndarrays harus .Tmengembalikan transpos, tetapi objek matriks juga memiliki .Htranspos konjugat, dan .Iuntuk invers.

Sebaliknya, numpy array secara konsisten mematuhi aturan bahwa operasi diterapkan berdasarkan elemen (kecuali untuk @operator baru ). Dengan demikian, jika adan barray numpy, maka a*barray dibentuk dengan mengalikan elemen-elemen komponen:

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

Untuk mendapatkan hasil perkalian matriks, Anda menggunakan np.dot(atau @dengan Python> = 3.5, seperti yang ditunjukkan di atas):

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

The **Operator juga berperilaku berbeda:

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

Karena amerupakan matriks, a**2kembalikan produk matriks a*a. Karena cmerupakan ndarray, c**2mengembalikan ndarray dengan setiap komponen yang dikuadratkan dengan elemen.

Ada perbedaan teknis lainnya antara objek matriks dan ndarrays (berkaitan dengan np.ravel, pemilihan item dan perilaku urutan).

Keuntungan utama dari array numpy adalah bahwa mereka lebih umum daripada matriks 2 dimensi . Apa yang terjadi ketika Anda menginginkan array 3 dimensi? Maka Anda harus menggunakan ndarray, bukan objek matriks. Dengan demikian, belajar menggunakan objek matriks lebih banyak pekerjaan - Anda harus belajar operasi objek matriks, dan operasi ndarray.

Menulis program yang menggabungkan matriks dan array membuat hidup Anda sulit karena Anda harus melacak jenis objek variabel Anda, jangan sampai perkalian mengembalikan sesuatu yang tidak Anda harapkan.

Sebaliknya, jika Anda hanya menggunakan ndarrays, maka Anda dapat melakukan semua yang dapat dilakukan objek matriks, dan lebih banyak lagi, kecuali dengan fungsi / notasi yang sedikit berbeda.

Jika Anda bersedia untuk melepaskan daya tarik visual dari notasi produk NumPy matrix (yang dapat dicapai hampir sama anggunnya dengan ndarrays dengan Python> = 3.5), maka saya pikir array NumPy jelas merupakan cara yang harus dilakukan.

PS. Tentu saja, Anda benar-benar tidak harus memilih satu dengan mengorbankan yang lain, karena np.asmatrixdan np.asarraymemungkinkan Anda untuk mengkonversi satu ke yang lain (selama array 2-dimensi).


Ada sinopsis dari perbedaan antara NumPy arraysvs NumPy matrixes di sini .

unutbu
sumber
7
Bagi mereka yang bertanya-tanya, mat**nuntuk sebuah matriks dapat diterapkan secara tidak reduce(np.dot, [arr]*n)
sengaja
6
Atau hanyanp.linalg.matrix_power(mat, n)
Eric
Saya bertanya-tanya apakah matriks akan lebih cepat ... Anda akan berpikir mereka harus melakukan kurang dari pemeriksaan ndarray.
PascalVKooten
1
Sebenarnya, tes timeit menunjukkan operasi ndarray seperti np.dot(array2, array2)lebih cepat daripada matrix1*matrix2. Ini masuk akal karena matrixmerupakan subclass dari ndarray yang menimpa metode khusus seperti __mul__. matrix.__mul__panggilannp.dot . Jadi ada penggunaan kembali kode di sini. Alih-alih melakukan lebih sedikit pemeriksaan, menggunakan matrix*matrixmembutuhkan panggilan fungsi tambahan. Jadi keuntungan menggunakan matrixsintaksis murni, bukan kinerja yang lebih baik.
unutbu
4 * 1 + 3 * 3 memberi Anda 13 ketika Anda melakukan np.dot (c, d) bukankah ini sebenarnya disebut produk silang dalam matematika
PirateApp
92

Scipy.org merekomendasikan agar Anda menggunakan array:

* 'array' atau 'matrix'? Yang mana yang harus saya gunakan? - Jawaban singkat

Gunakan array.

  • Mereka adalah tipe vektor / matriks / tensor standar numpy. Banyak fungsi numpy mengembalikan array, bukan matriks.

  • Ada perbedaan yang jelas antara operasi elemen-bijaksana dan operasi aljabar linier.

  • Anda dapat memiliki vektor standar atau vektor baris / kolom jika diinginkan.

Satu-satunya kelemahan menggunakan jenis array adalah bahwa Anda harus menggunakan dotalih-alih *mengalikan (mengurangi) dua tensor (produk skalar, perkalian vektor matriks, dll.).

atomh33ls
sumber
11
Meskipun jawaban yang diterima memberikan lebih banyak info, jawaban yang sebenarnya adalah tetap dengan ndarray. Argumen utama untuk menggunakan matrixakan jika kode Anda berat dalam aljabar linier dan akan terlihat kurang jelas dengan semua panggilan ke dotfungsi. Tapi argumen ini akan hilang di masa depan, sekarang @ -operator diterima untuk digunakan dengan perkalian matriks, lihat PEP 465 . Ini akan membutuhkan Python 3.5 dan versi terbaru Numpy. Kelas matriks mungkin sudah ditinggalkan jauh di masa depan, jadi lebih baik menggunakan ndarray untuk kode baru ...
Bas Swinckels
6
Halaman itu dengan anggun lupa tentang scipy.sparsematriks. Jika Anda menggunakan matriks padat & jarang dalam kode Anda, itu jauh lebih mudah untuk dipatuhi matrix.
David Nemeskey
3
Menurut pendapat saya, kerugian utama dari array adalah bahwa slicing kolom mengembalikan array datar yang dapat membingungkan dan secara matematis tidak terlalu bagus. Ini juga mengarah pada kerugian penting bahwa array numpy tidak dapat diperlakukan dengan cara yang sama seperti matriks scipy.sparse sedangkan matriks numpy pada dasarnya dapat ditukar secara bebas dengan matriks jarang. Agak tidak masuk akal dalam konteks ini bahwa Scipy merekomendasikan penggunaan array dan kemudian tidak menyediakan array jarang yang kompatibel.
Radio Terkendali
29

Hanya dengan menambahkan satu case ke daftar unutbu.

Salah satu perbedaan praktis terbesar bagi saya ndarrays numpy dibandingkan dengan matriks numpy atau bahasa matriks seperti matlab, adalah bahwa dimensi tidak dipertahankan dalam mengurangi operasi. Matriks selalu 2d, sedangkan rata-rata array, misalnya, memiliki satu dimensi lebih sedikit.

Misalnya, merendahkan baris matriks atau array:

dengan matriks

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

dengan array

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

Saya juga berpikir bahwa mencampur array dan matriks memunculkan banyak jam debug yang "bahagia". Namun, matriks scipy.sparse selalu matriks dalam hal operator seperti perkalian.

Josef
sumber
20

Seperti yang telah disebutkan orang lain, mungkin keuntungan utama matrixadalah memberikan notasi yang nyaman untuk perkalian matriks.

Namun, di Python 3.5 akhirnya ada operator infiks khusus untuk perkalian matriks : @.

Dengan versi NumPy terbaru, ini dapat digunakan dengan ndarrays:

A = numpy.ones((1, 3))
B = numpy.ones((3, 3))
A @ B

Jadi saat ini, bahkan lebih, ketika ragu, Anda harus tetap melakukannya ndarray.

Peque
sumber