सुन्न सरणियों और मैट्रिक्स के बीच अंतर क्या हैं? मुझे किसका उपयोग करना चाहिए?


346

हर एक के फायदे और नुकसान क्या हैं?

मैंने जो देखा है, उसमें से कोई भी एक दूसरे के प्रतिस्थापन के रूप में काम कर सकता है, अगर जरूरत हो, तो क्या मुझे दोनों का उपयोग करने में परेशान होना चाहिए या क्या मुझे उनमें से सिर्फ एक से चिपकना चाहिए?

क्या कार्यक्रम की शैली मेरी पसंद को प्रभावित करेगी? मैं कुछ मशीन सीखने का उपयोग कर रहा हूँ, ताकि वास्तव में बहुत सारे मैट्रिस हों, लेकिन बहुत सारे वैक्टर (सरणियाँ) भी।


3
मेरे पास एक उत्तर को सही ठहराने के लिए पर्याप्त जानकारी नहीं है लेकिन मैं जो मुख्य अंतर बता सकता हूं वह गुणा का कार्यान्वयन है। एक मैट्रिक्स मैट्रिक्स / टैंसर गुणन करता है, जबकि एक सरणी तत्व-वार गुणन करेगा।
बजे माइक एसेक

5
Python 3.5 ने मैट्रिक्स गुणा (PEP 465) के लिए infix @ ऑपरेटर को जोड़ा, और इसके लिए NumPy 1.10 ने समर्थन जोड़ा। तो अगर आप अजगर 3.5+ का उपयोग करने और NumPy 1.10+ कर रहे हैं, तो आप सिर्फ लिख सकते हैं A @ Bके बजाय A.dot(B), जहां Aऔर Bकर रहे हैं 2 डी ndarrayएस। यह matrixसादे ndarrayएस, आईएमएचओ के बजाय उपयोग करने का मुख्य लाभ निकालता है ।
मिनीक्वायार्क

जवाबों:


4

आधिकारिक दस्तावेजों के अनुसार, भविष्य में हटाए जाने के बाद से मैट्रिक्स क्लास का उपयोग करना उचित नहीं है।

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

जैसा कि अन्य उत्तर पहले ही बता चुके हैं कि आप सभी ऑपरेशन को NumPy सरणियों से प्राप्त कर सकते हैं।


396

Numpy matrices कड़ाई से 2-आयामी हैं, जबकि सुन्न arrays (ndarrays) N-आयामी हैं। मैट्रिक्स ऑब्जेक्ट ndarray का एक उपवर्ग हैं, इसलिए वे ndarrays की सभी विशेषताओं और विधियों को विरासत में लेते हैं।

सुपीरियर मेट्रिसेस का मुख्य लाभ यह है कि वे मैट्रिक्स गुणन के लिए एक सुविधाजनक अंकन प्रदान करते हैं: यदि ए और बी मैट्रिस हैं, तो 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 मैट्रिक्स गुणा का समर्थन करता है , इसलिए आप Python> = 3.5 में ndarrays के साथ मैट्रिक्स गुणा की समान सुविधा प्राप्त कर सकते हैं।

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व्युत्क्रम के लिए भी है।

इसके विपरीत, सुन्न सरणियाँ लगातार इस नियम का पालन करती हैं कि संचालन को तत्व-वार (नए @ऑपरेटर को छोड़कर ) लागू किया जाता है । इस प्रकार, यदि aऔर bNumPy सरणी हैं, तो 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(या @ऊपर दिखाए गए अनुसार पायथन> = 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आइटम चयन और अनुक्रम व्यवहार के साथ क्या करना है) के बीच अन्य तकनीकी अंतर हैं ।

सुन्न सरणियों का मुख्य लाभ यह है कि वे 2-आयामी मेट्रिसेस की तुलना में अधिक सामान्य हैं । क्या होता है जब आप एक 3-आयामी सरणी चाहते हैं? तब आपको एक ndarray का उपयोग करना होगा, न कि मैट्रिक्स ऑब्जेक्ट। इस प्रकार, मैट्रिक्स ऑब्जेक्ट्स का उपयोग करना सीखना अधिक काम है - आपको मैट्रिक्स ऑब्जेक्ट संचालन, और ndarray संचालन सीखना होगा।

एक प्रोग्राम लिखना जो मैट्रिसेस और सरणियों दोनों को मिलाता है, आपके जीवन को कठिन बनाता है क्योंकि आपको इस बात का ट्रैक रखना होगा कि आपके चर किस प्रकार के ऑब्जेक्ट हैं, ऐसा न हो कि गुणा गुणक कुछ ऐसी चीज़ लौटाए जिसकी आपको उम्मीद नहीं है।

इसके विपरीत, यदि आप पूरी तरह से ndarrays के साथ चिपके रहते हैं, तो आप कुछ भी अलग-अलग कार्यों / संकेतन को छोड़कर मैट्रिक्स की सभी चीजें कर सकते हैं, और अधिक कर सकते हैं।

यदि आप NumPy मैट्रिक्स उत्पाद संकेतन की दृश्य अपील को छोड़ने के लिए तैयार हैं (जिसे Python> = 3.5 में ndarrays के साथ लगभग समान रूप से प्राप्त किया जा सकता है), तो मुझे लगता है कि NumPy सरणियाँ निश्चित रूप से जाने का रास्ता हैं।

पुनश्च। बेशक, आपको वास्तव में दूसरे की कीमत पर एक को चुनने की ज़रूरत नहीं है, क्योंकि np.asmatrixऔर np.asarrayआपको एक को दूसरे में बदलने की अनुमति है (जब तक कि सरणी 2-आयामी है)।


वहाँ NumPy के बीच मतभेद का सारांश है arraysबनाम NumPy matrixतों यहाँ


7
सोच रहे लोगों के mat**nलिए , एक मैट्रिक्स के लिए एक reduce(np.dot, [arr]*n)
असमान

6
या सिर्फnp.linalg.matrix_power(mat, n)
एरिक

मैं सोच रहा था कि क्या मैटरिस तेज होगा ... आपको लगता है कि उन्हें ndarray की तुलना में कम जांच करनी होगी।
पास्कलवूटन

1
वास्तव में, समय पर परीक्षण ndarray संचालन दिखाते np.dot(array2, array2)हैं जैसे कि तेजी से होता है matrix1*matrix2। यह समझ में आता है क्योंकि matrixndarray का एक उपवर्ग है जो विशेष तरीकों को ओवरराइड करता है जैसे __mul__matrix.__mul__कॉल करता हैnp.dot । तो यहाँ पर कोड रीज़न है। कम जांच करने के बजाय, matrix*matrixअतिरिक्त फ़ंक्शन कॉल की आवश्यकता होती है। तो उपयोग करने matrixका लाभ विशुद्ध रूप से वाक्यात्मक है, बेहतर प्रदर्शन नहीं।
२४:

4 * 1 + 3 * 3 आपको 13 दे रहा है जब आपने np.dot (c, d) को वास्तव में गणित में क्रॉस उत्पाद नहीं कहा है
PirateApp

92

Scipy.org अनुशंसा करता है कि आप सरणियों का उपयोग करें:

* 'सरणी' या 'मैट्रिक्स'? मुझे कौन सा उपयोग करना चाहिए? - संक्षिप्त जवाब

सरणियों का उपयोग करें।

  • वे मानक वेक्टर / मैट्रिक्स / दसवें प्रकार के सुन्न हैं। कई संख्यात्मक कार्य रिटर्न सरणियाँ, मेट्रिसेस नहीं।

  • तत्व-वार संचालन और रैखिक बीजगणित संचालन के बीच एक स्पष्ट अंतर है।

  • यदि आप चाहें तो आपके पास मानक वैक्टर या पंक्ति / स्तंभ वैक्टर हो सकते हैं।

सरणी प्रकार का उपयोग करने का एकमात्र नुकसान यह है कि आपको दो टेनर्स (स्केलर उत्पाद, मैट्रिक्स वेक्टर गुणन आदि) को गुणा (कम) करने के dotबजाय उपयोग करना होगा *


11
भले ही स्वीकृत उत्तर अधिक जानकारी प्रदान करता है, लेकिन वास्तविक उत्तर वास्तव में साथ रहना है ndarray। उपयोग करने के लिए मुख्य तर्क यह matrixहोगा कि यदि आपका कोड रैखिक बीजगणित में भारी है और dotफ़ंक्शन के सभी कॉल के साथ कम स्पष्ट दिखाई देगा । लेकिन यह तर्क भविष्य में गायब हो जाएगा, अब जब मैट्रिक्स मैट्रिक्स के साथ उपयोग के लिए @ -प्रोसेसर स्वीकार किया जाता है, तो PEP 465 देखें । इसके लिए पायथन 3.5 और नेम्पी के नवीनतम संस्करण की आवश्यकता होगी। मैट्रिक्स वर्ग को दूर भविष्य में पदावनत किया जा सकता है, इसलिए नए कोड के लिए
ndarray

6
वह पृष्ठ शालीनता से scipy.sparseमेट्रिसेस के बारे में भूल जाता है । यदि आप अपने कोड में घने और विरल मैट्रिस दोनों का उपयोग करते हैं, तो यह छड़ी करना बहुत आसान है matrix
डेविड नेमेस्की

3
मेरी राय में, सरणियों का मुख्य नुकसान यह है कि स्तंभ टुकड़ा करने वाले फ्लैट सरणियों को लौटाते हैं जो भ्रमित हो सकते हैं और गणितीय रूप से वास्तव में ध्वनि है। इससे यह महत्वपूर्ण नुकसान भी होता है कि खसखस ​​को उसी तरह से नहीं माना जा सकता है जैसे कि scipy.sparse matrices जबकि numpy matrices मूल रूप से विरल मैट्रिस के साथ स्वतंत्र रूप से आदान-प्रदान किया जा सकता है। इस संदर्भ में बेतुका की तरह कि डरपोक सरणियों का उपयोग करने की सिफारिश करता है और फिर संगत विरल सरणियाँ प्रदान नहीं करता है।
रेडियो

29

बस एक मामले को unutbu की सूची में जोड़ने के लिए।

मैटलैब जैसे मैट्रिक्स मैक्रिसेस या मैट्रिक्स लैंग्वेज की तुलना में मेरे लिए सबसे बड़ी व्यावहारिक भिन्नताओं में से एक है, यह है कि आयाम कम संचालन में संरक्षित नहीं है। मैट्रिक्स हमेशा 2d होते हैं, जबकि एक सरणी का मतलब, उदाहरण के लिए, एक आयाम कम है।

उदाहरण के लिए मैट्रिक्स या एरे की डेमियन रो:

मैट्रिक्स के साथ

>>> 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 मैट्रिसेस हमेशा गुणा जैसे ऑपरेटरों के संदर्भ में मैट्रिसेस होते हैं।


20

जैसा कि दूसरों ने उल्लेख किया है, शायद इसका मुख्य लाभ matrixयह था कि यह मैट्रिक्स गुणन के लिए एक सुविधाजनक अंकन प्रदान करता था।

हालांकि, अजगर 3.5 में वहाँ अंत में आव्यूह गुणन के लिए एक समर्पित इन्फ़िक्स ऑपरेटर है : @

हाल के NumPy संस्करणों के साथ, इसे ndarrays के साथ प्रयोग किया जा सकता है :

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

तो आजकल, और भी, जब संदेह में, तुम से चिपके रहना चाहिए ndarray

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.