2010-11-11 60 views
245

Những ưu điểm và nhược điểm của mỗi loại là gì?Sự khác nhau giữa mảng và ma trận có nhiều mảng là gì? Tôi nên sử dụng cái nào?

Từ những gì tôi đã thấy, một trong hai có thể làm việc thay thế cho người khác nếu cần thiết, vì vậy tôi nên sử dụng cả hai hoặc tôi nên dính vào chỉ một trong số họ?

Phong cách của chương trình có ảnh hưởng đến lựa chọn của tôi không? Tôi đang làm một số máy học bằng cách sử dụng numpy, do đó, có thực sự rất nhiều ma trận, nhưng cũng có rất nhiều vectơ (mảng).

+2

Tôi không có đủ thông tin để biện minh cho câu trả lời nhưng từ những gì tôi có thể cho biết sự khác biệt chính là triển khai phép nhân. Một ma trận thực hiện phép nhân/ma trận tensor, trong khi một mảng sẽ làm phép nhân phần tử. –

+2

Python 3.5 đã thêm toán tử @ infix cho phép nhân ma trận (PEP 465) và NumPy 1.10 hỗ trợ thêm cho nó. Vì vậy, nếu bạn đang sử dụng Python 3.5+ và NumPy 1.10+, thì bạn chỉ có thể viết 'A @ B' thay vì' A.dot (B) ', trong đó' A' và 'B' là 2D' ndarray's. Điều này loại bỏ lợi thế chính của việc sử dụng 'ma trận' thay vì' ndarray' đơn giản, IMHO. – MiniQuark

Trả lời

283

Ma trận có khối lượng nghiêm ngặt là 2 chiều, trong khi mảng có nhiều mảng (ndarrays) là N-chiều. Các đối tượng ma trận là một phân lớp của ndarray, do đó, chúng kế thừa tất cả các thuộc tính và phương thức của ndarrays .

Ưu điểm chính của ma trận khó khăn là chúng cung cấp ký hiệu thuận tiện cho phép nhân ma trận: nếu a và b là ma trận, thì a * b là ma trận sản phẩm.

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

Mặt khác, tính đến Python 3.5, NumPy hỗ trợ ghi vào ma trận nhân sử dụng toán tử @, vì vậy bạn có thể đạt được sự tiện lợi cùng của phép nhân ma trận với ndarrays bằng Python> = 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]] 

Cả hai đối tượng ma trận và ndarrays có .T để trả lại chuyển vị, nhưng ma trận đối tượng cũng có .H cho chuyển vị liên hợp, và .I cho nghịch đảo.

Ngược lại, mảng cố định luôn tuân theo quy tắc hoạt động là được áp dụng thành phần khôn ngoan (trừ toán tử @ mới). Vì vậy, nếu ab là mảng NumPy, sau đó a*b là mảng hình thành bằng cách nhân các thành phần nguyên tố khôn ngoan:

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

Để có được kết quả của phép nhân ma trận, bạn sử dụng np.dot (hoặc @ bằng Python> = 3.5, như trình bày ở trên):

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

Nhà điều hành ** cũng cư xử khác nhau:

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

a là ma trận, a**2 trả về sản phẩm ma trận a*a. Vì c là một số thứ tự, c**2 trả về một dấu sao với mỗi thành phần bình phương yếu tố khôn ngoan.

Có sự khác biệt kỹ thuật khác giữa các đối tượng ma trận và ndarrays (phải làm với np.ravel, chọn mục và hành vi trình tự).

Ưu điểm chính của mảng có nhiều mảng là chúng tổng quát hơn ma trận 2 chiều. Điều gì xảy ra khi bạn muốn một mảng 3 chiều? Sau đó, bạn phải sử dụng một đối tượng ma trận, không phải là ma trận.Vì vậy, việc học sử dụng ma trận đối tượng là công việc nhiều hơn - bạn phải học các hoạt động đối tượng ma trận và các hoạt động ndarray .

Viết chương trình sử dụng cả ma trận và mảng làm cho cuộc sống của bạn trở nên khó khăn vì bạn phải theo dõi loại đối tượng mà biến của bạn đang sử dụng, vì sợ rằng bạn không mong đợi điều gì.

Ngược lại, nếu bạn chỉ gắn bó với các ô, bạn có thể làm mọi thứ đối tượng ma trận có thể thực hiện, và nhiều hơn nữa, ngoại trừ các chức năng/ký hiệu hơi khác nhau .

Nếu bạn sẵn sàng từ bỏ sự hấp dẫn trực quan của sản phẩm ma trận NumPy ký hiệu (có thể đạt được gần như thanh lịch với ndarrays bằng Python> = 3.5), thì tôi nghĩ mảng NumPy chắc chắn là con đường để đi.

PS. Tất nhiên, bạn thực sự không phải chọn một chi phí khác, kể từ np.asmatrixnp.asarray cho phép bạn chuyển đổi một cái khác (như miễn là mảng là 2 chiều).


Có một tóm tắt của sự khác biệt giữa NumPy arrays vs NumPy matrix es here.

+5

Đối với những người tự hỏi, 'mat ** n' cho một ma trận có thể không được áp dụng cho một mảng với' reduce (np.dot, [arr] * n) ' – askewchan

+2

Hoặc chỉ' np.linalg.matrix_power (mat, n) ' – Eric

+0

Tôi tự hỏi liệu ma trận có nhanh hơn không ... bạn nghĩ rằng chúng phải thực hiện các phép kiểm tra ít hơn so với ndarray. – PascalVKooten

23

Chỉ cần thêm một trường hợp vào danh sách của unutbu.

Một trong những sự khác biệt thực tế lớn nhất đối với tôi về ma trận khó khăn so với ma trận cứng nhắc hoặc các ngôn ngữ ma trận như MATLAB, là kích thước không được bảo toàn trong hoạt động giảm. Ma trận luôn là 2d, trong khi giá trị trung bình của một mảng chẳng hạn, có một chiều ít hơn.

Ví dụ hạ thấp hàng của một ma trận hoặc mảng:

với ma trận

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

với mảng

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

Tôi cũng nghĩ rằng pha trộn các mảng và ma trận làm phát sinh nhiều "hạnh phúc "gỡ lỗi giờ. Tuy nhiên, ma trận scipy.sparse luôn luôn là ma trận về các toán tử như phép nhân.

69

Scipy.org recommends that you use arrays:

* 'mảng' hoặc 'ma trận'? Tôi nên sử dụng cái nào? - Câu trả lời ngắn

Sử dụng mảng.

  • Chúng là loại véc-tơ tiêu chuẩn/ma trận/tensor tiêu chuẩn. Nhiều mảng trả về hàm không có vón cục, không phải ma trận.

  • Có sự phân biệt rõ ràng giữa các hoạt động khôn ngoan với yếu tố và hoạt động đại số tuyến tính.

  • Bạn có thể có vectơ chuẩn hoặc vectơ hàng/cột nếu muốn.

Nhược điểm duy nhất của việc sử dụng các loại mảng là bạn sẽ phải sử dụng dot thay vì * nhân (giảm) hai tensors (sản phẩm vô hướng, ma trận vector nhân vv).

+6

Mặc dù câu trả lời được chấp nhận cung cấp thêm thông tin, câu trả lời thực sự thực sự là gắn bó với 'ndarray'. Đối số chính để sử dụng 'ma trận' sẽ là nếu mã của bạn nặng trong đại số tuyến tính và sẽ ít rõ ràng hơn với tất cả các cuộc gọi đến hàm' dấu chấm'. Nhưng đối số này sẽ biến mất trong tương lai, bây giờ mà @ -operator được chấp nhận để sử dụng với phép nhân, xem [PEP 465] (https://www.python.org/dev/peps/pep-0465/). Điều này sẽ cần Python 3.5 và phiên bản mới nhất của Numpy. Lớp ma trận có thể bị phản đối trong tương lai xa, vì vậy tốt hơn nên sử dụng ndarray cho mã mới ... –

+4

Trang đó ân cần quên về ma trận 'scipy.sparse'. Nếu bạn sử dụng cả hai ma trận dày đặc và thưa thớt trong mã của bạn, nó sẽ dễ dàng hơn để gắn vào 'ma trận'. –

+1

Theo tôi, nhược điểm chính của mảng là việc cắt cột trả về mảng phẳng có thể gây nhầm lẫn và toán học không thực sự âm thanh. Điều này cũng dẫn đến những bất lợi quan trọng mà mảng numpy không thể được xử lý trong cùng một cách như ma trận scipy.sparse trong khi ma trận numpy về cơ bản có thể được trao đổi một cách tự do với ma trận thưa thớt. Loại vô lý trong bối cảnh này mà scipy khuyến cáo sử dụng mảng và sau đó không cung cấp mảng thưa thớt tương thích. –

13

Như những người khác đã đề cập, có lẽ lợi thế chính của matrix là nó cung cấp ký hiệu thuận tiện cho phép nhân ma trận.

Tuy nhiên, in Python 3.5 there is finally a dedicated infix operator for matrix multiplication: @.

Với phiên bản gần đây NumPy, nó có thể được sử dụng với ndarray s:

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

Vì vậy, ngày nay, thậm chí nhiều, khi nghi ngờ, bạn nên dính vào ndarray.

Các vấn đề liên quan