อะไรคือความแตกต่างระหว่างอาร์เรย์ numpy และเมทริกซ์? ฉันควรใช้อันไหนดี


346

ข้อดีและข้อเสียของแต่ละข้อคืออะไร

จากสิ่งที่ฉันได้เห็นคนใดคนหนึ่งสามารถทำงานแทนคนอื่นได้ถ้าต้องการดังนั้นฉันควรจะใช้ทั้งสองอย่างหรือติดอยู่กับคนใดคนหนึ่ง?

รูปแบบของโปรแกรมจะมีผลต่อการเลือกของฉันหรือไม่? ฉันกำลังเรียนรู้เครื่องจักรด้วยการใช้ numpy ดังนั้นจึงมีเมทริกซ์จำนวนมาก แต่มีเวกเตอร์จำนวนมาก (อาร์เรย์)


3
ฉันไม่มีข้อมูลเพียงพอที่จะพิสูจน์คำตอบ แต่จากสิ่งที่ฉันสามารถบอกความแตกต่างที่สำคัญคือการใช้การคูณ เมทริกซ์ทำการคูณเมทริกซ์ / เทนเซอร์ในขณะที่อาร์เรย์จะทำการคูณองค์ประกอบที่ชาญฉลาด
Mike Axiak

5
Python 3.5 เพิ่มตัวดำเนินการ infix @ สำหรับการคูณเมทริกซ์ (PEP 465) และ NumPy 1.10 เพิ่มการรองรับ ดังนั้นถ้าคุณกำลังใช้ Python 3.5 ขึ้นไปและ NumPy 1.10+ แล้วคุณก็สามารถเขียนA @ BแทนการA.dot(B)ที่AและBมี 2D ndarrays สิ่งนี้จะลบข้อได้เปรียบหลักของการใช้matrixแทนการใช้ธรรมดาndarray, IMHO
MiniQuark

คำตอบ:


4

ตามเอกสารทางการไม่แนะนำให้ใช้คลาสเมทริกซ์อีกต่อไปเนื่องจากจะถูกลบออกในอนาคต

https://numpy.org/doc/stable/reference/generated/numpy.matrix.html

ตามที่คำตอบอื่น ๆ ระบุไว้แล้วว่าคุณสามารถบรรลุการดำเนินการทั้งหมดด้วย NumPy arrays


396

Numpy matricesเป็น 2 มิติอย่างเคร่งครัดในขณะที่ numpy arrays (ndarrays) เป็น N-dimension วัตถุเมทริกซ์เป็นคลาสย่อยของ ndarray ดังนั้นพวกเขาจึงสืบทอดคุณสมบัติและวิธีการของ ndarray ทั้งหมด

ข้อได้เปรียบหลักของเมทริกซ์ numpy ก็คือพวกมันให้สัญกรณ์ที่สะดวกสำหรับการคูณเมทริกซ์: ถ้า a และ b เป็นเมทริกซ์a*bนั่นคือผลคูณเมทริกซ์ของพวกมัน

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

ในทางตรงกันข้ามในฐานะของ Python 3.5 NumPy รองรับการคูณเมทริกซ์ infix โดยใช้@โอเปอเรเตอร์ดังนั้นคุณจะได้รับความสะดวกสบายเหมือนกันกับการคูณเมทริกซ์กับ ndarrays ใน 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]]

ทั้งเมทริกซ์ออบเจ็กต์และ ndarrays จะต้อง.Tส่งคืนทรานสโพสต์ แต่วัตถุเมทริกซ์ก็มี.Hไว้สำหรับคอนจูเกตทรานสคูนและ.Iอินเวอร์ส

ในทางตรงกันข้ามอาร์เรย์ numpy ปฏิบัติตามกฎที่การดำเนินการถูกนำไปใช้องค์ประกอบที่ชาญฉลาด (ยกเว้นสำหรับ@ผู้ประกอบการใหม่) ดังนั้นถ้าaและbเป็นอาร์เรย์ numpy แล้วa*bอาร์เรย์ที่เกิดขึ้นจากการคูณองค์ประกอบองค์ประกอบที่ชาญฉลาด:

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

ในการรับผลลัพธ์ของการคูณเมทริกซ์คุณใช้np.dot(หรือ@ใน Python> = 3.5 ดังที่แสดงด้านบน):

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

ตัว**ดำเนินการยังทำงานแตกต่างกัน:

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

ตั้งแต่aเป็นเมทริกซ์ผลตอบแทนผลิตภัณฑ์แมทริกซ์a**2 a*aเนื่องจากcเป็น ndarray ให้c**2ส่งคืน ndarray ด้วยองค์ประกอบแต่ละองค์ประกอบกำลังสองที่ชาญฉลาด

มีความแตกต่างทางเทคนิคอื่น ๆ ระหว่างวัตถุเมทริกซ์และ ndarrays (เกี่ยวข้องกับการnp.ravelเลือกรายการและพฤติกรรมการเรียงลำดับ)

ประโยชน์หลักของอาร์เรย์ numpy คือพวกเขามีทั่วไปมากขึ้นกว่าการฝึกอบรม จะเกิดอะไรขึ้นเมื่อคุณต้องการอาร์เรย์สามมิติ ถ้าอย่างนั้นคุณต้องใช้ ndarray ไม่ใช่วัตถุเมทริกซ์ ดังนั้นการเรียนรู้ที่จะใช้วัตถุเมทริกซ์เป็นงานที่มากขึ้น - คุณต้องเรียนรู้การทำงานของวัตถุเมทริกซ์และการดำเนินการตามลำดับ

การเขียนโปรแกรมที่ผสมทั้งเมทริกซ์และอาเรย์ทำให้ชีวิตของคุณลำบากเพราะคุณต้องคอยติดตามว่าวัตถุของคุณเป็นตัวแปรประเภทใดเพื่อไม่ให้การคูณทวีคืนสิ่งที่คุณไม่คาดคิด

ในทางตรงกันข้ามหากคุณยึดติดกับ ndarrays เพียงอย่างเดียวคุณสามารถทำทุกสิ่งที่วัตถุเมทริกซ์สามารถทำได้และอื่น ๆ ยกเว้นฟังก์ชั่น / สัญกรณ์ที่แตกต่างกันเล็กน้อย

หากคุณยินดีที่จะยอมแพ้การดึงดูดสายตาของสัญกรณ์ผลิตภัณฑ์ NumPy matrix (ซึ่งสามารถทำได้เกือบจะหรูหราด้วย ndarrays ใน Python> = 3.5) ฉันคิดว่าอาร์เรย์ของ NumPy เป็นหนทางที่แน่นอนที่จะไป

PS แน่นอนคุณจริงๆไม่ต้องเลือกอย่างใดอย่างหนึ่งที่ค่าใช้จ่ายของคนอื่นตั้งแต่np.asmatrixและnp.asarrayช่วยให้คุณสามารถแปลงหนึ่งไปยังอีก (ตราบเท่าที่อาร์เรย์ 2 มิติ)


มีบทสรุปของความแตกต่างระหว่าง NumPy คือarraysVS NumPy matrixes นี่


7
สำหรับผู้ที่สงสัยว่าmat**nจะสามารถนำเมทริกซ์มาใช้กับอาร์เรย์ได้อย่างไม่แน่นอนด้วยreduce(np.dot, [arr]*n)
askewchan

6
หรือเพียงแค่np.linalg.matrix_power(mat, n)
Eric

ฉันสงสัยว่าการฝึกอบรมจะเร็วกว่านี้หรือไม่ ... คุณคิดว่าพวกเขาจะต้องทำการตรวจสอบน้อยกว่า ndarray
PascalVKooten

1
อันที่จริงการทดสอบแสดงให้เห็นการดำเนินงาน timeit ndarray เช่นจะเร็วกว่าnp.dot(array2, array2) matrix1*matrix2นี้ทำให้รู้สึกเพราะmatrixเป็น subclass ของ ndarray __mul__ซึ่งแทนที่วิธีพิเศษเช่น โทรmatrix.__mul__ np.dotดังนั้นจึงมีรหัส reusage ที่นี่ แทนที่จะทำการตรวจสอบน้อยลงการใช้matrix*matrixต้องใช้การเรียกฟังก์ชันพิเศษ ดังนั้นข้อดีของการใช้matrixคือ syntactic ล้วนๆ, ไม่ใช่ประสิทธิภาพที่ดีขึ้น
unutbu

4 * 1 + 3 * 3 ให้คุณ 13 ตอนที่คุณทำ np.dot (c, d) ไม่ใช่สิ่งนี้เรียกว่า cross product ในคณิตศาสตร์
PirateApp

92

Scipy.org แนะนำให้คุณใช้อาร์เรย์:

* 'array' หรือ 'matrix'? ฉันควรใช้อันไหนดี? - คำตอบสั้น ๆ

ใช้อาร์เรย์

  • เป็นเวกเตอร์ / เมทริกซ์ / เทนเซอร์ประเภทมาตรฐาน ฟังก์ชันส่งคืนอาร์เรย์จำนวนมากไม่ใช่เมทริกซ์

  • มีความแตกต่างที่ชัดเจนระหว่างการทำงานขององค์ประกอบที่ชาญฉลาดและการดำเนินงานพีชคณิตเชิงเส้น

  • คุณสามารถมีเวกเตอร์มาตรฐานหรือเวกเตอร์แถว / คอลัมน์ได้ถ้าต้องการ

ข้อเสียเพียงอย่างเดียวของการใช้ประเภทอาเรย์คือคุณจะต้องใช้dotแทน*การคูณ (ลด) เทนเซอร์สองตัว (ผลิตภัณฑ์สเกลาร์, การคูณเมทริกซ์เวกเตอร์ ฯลฯ )


11
ndarrayถึงแม้ว่าคำตอบที่ได้รับการยอมรับให้ข้อมูลเพิ่มเติมคำตอบที่แท้จริงย่อมที่จะติดกับ อาร์กิวเมนต์หลักสำหรับการใช้งานmatrixคือถ้ารหัสของคุณหนักในพีชคณิตเชิงเส้นและจะดูชัดเจนน้อยลงเมื่อมีการเรียกใช้dotฟังก์ชันทั้งหมด แต่เรื่องนี้จะหายไปในอนาคตตอนนี้ที่ @ -operator เป็นที่ยอมรับสำหรับการใช้งานกับคูณเมทริกซ์ดูPEP 465 สิ่งนี้จะต้องใช้ Python 3.5 และ Numpy เวอร์ชันล่าสุด คลาสเมทริกซ์อาจเลิกใช้ในอนาคตอันไกลดังนั้นควรใช้ ndarray สำหรับรหัสใหม่ ...
Bas Swinckels

6
หน้านั้นลืมเรื่องscipy.sparseเมทริกซ์ matrixหากคุณใช้ทั้งความหนาแน่นและการฝึกอบรมเบาบางในรหัสของคุณมันเป็นเรื่องง่ายมากที่จะติด
David Nemeskey

3
ในความคิดของฉันข้อเสียเปรียบหลักของอาร์เรย์คือการที่การแบ่งคอลัมน์จะส่งกลับอาร์เรย์แบบแบนซึ่งอาจทำให้เกิดความสับสนและในทางคณิตศาสตร์ไม่ได้ฟัง สิ่งนี้ยังนำไปสู่ข้อเสียที่สำคัญที่อาร์เรย์ numpy ไม่สามารถรับการรักษาด้วยวิธีเดียวกันกับ scipy.sparse matrices ขณะที่เมทริกซ์ numpy โดยทั่วไปสามารถแลกเปลี่ยนได้อย่างอิสระกับเมทริกซ์กระจัดกระจาย ชนิดของความบ้าบอในบริบทนี้ที่ scipy แนะนำให้ใช้อาร์เรย์และจากนั้นไม่ได้จัดให้มีกระจัดกระจายอาร์เรย์
วิทยุควบคุม

29

เพียงเพิ่มกรณีหนึ่งไปยังรายการของ unutbu

หนึ่งในความแตกต่างในทางปฏิบัติที่ใหญ่ที่สุดสำหรับฉันของ numpy ndarrays เมื่อเปรียบเทียบกับเมทริกซ์ numpy หรือภาษาเมทริกซ์เช่น matlab คือมิติไม่ได้ถูกสงวนไว้ในการลดการดำเนินการ เมทริกซ์จะเป็น 2d เสมอในขณะที่ค่าเฉลี่ยของอาร์เรย์มีน้อยกว่าหนึ่งมิติ

ตัวอย่างเช่นแถว demean ของเมทริกซ์หรืออาร์เรย์:

ด้วยเมทริกซ์

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

กับอาร์เรย์

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

ฉันยังคิดว่าการผสมอาร์เรย์และเมทริกซ์ก่อให้เกิดชั่วโมงการดีบักที่ "มีความสุข" มากมาย อย่างไรก็ตาม scipy.sparse เมทริกซ์เป็นเมทริกซ์เสมอในแง่ของตัวดำเนินการเช่นการคูณ


21

ดังที่คนอื่น ๆ พูดถึงบางทีข้อได้เปรียบหลักของmatrixมันคือมันให้สัญกรณ์ที่สะดวกสำหรับการคูณเมทริกซ์

อย่างไรก็ตามในหลาม 3.5 มีในที่สุดผู้ประกอบการมัดเฉพาะสำหรับคูณเมทริกซ์@ :

ด้วยเวอร์ชัน NumPy ล่าสุดสามารถใช้กับndarrays:

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

ndarrayดังนั้นในปัจจุบันมากยิ่งขึ้นเมื่อมีข้อสงสัยคุณควรจะติด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.