NumPy ম্যাট্রিক্স বনাম অ্যারে ক্লাসগুলির জন্য কীভাবে গুণন আলাদা হয়?


130

নাম্বার ডক্স ম্যাট্রিক্সের সাথে কাজ করার জন্য ম্যাট্রিক্সের পরিবর্তে অ্যারে ব্যবহার করার পরামর্শ দেয়। তবে, অষ্টাভে (যা আমি সম্প্রতি অবধি ব্যবহার করছিলাম) এর বিপরীতে, * ম্যাট্রিক্স গুণন করে না, আপনাকে ম্যাট্রিক্স মাল্টিপি () ব্যবহার করতে হবে। আমি মনে করি এটি কোডটি খুব অপঠনযোগ্য করে তুলেছে।

কেউ কি আমার মতামত শেয়ার করে সমাধান খুঁজে পেয়েছে?


8
আপনি মতামত চাইছেন, একটি প্রশ্ন নয়। আরও কিছু সুনির্দিষ্ট কিছু রয়েছে যার সাথে আমরা আপনাকে সহায়তা করতে পারি বা সম্ভবত এটিকে আরও পাঠযোগ্য করে তুলতে আপনাকে গাইড করতে পারি?
Wheaties

2
আসলে ডকস ম্যাট্রিক্স ব্যবহারের পরামর্শ দিচ্ছেন যদি আপনি লিনিয়ার বীজগণিত করেন এবং বহুগুণ () ব্যবহার করতে চান না তাহলে সমস্যা কী?
ম্যাটি প্যাসেল

1
আমি বিস্তারিতভাবে ডক্সের মধ্য দিয়ে যাইনি। শুধু কৌতূহলী, ম্যাট্রিক্স ক্লাসের জন্য অ্যারে কী সুবিধা দেয়? আমি দেখতে পেয়েছি যে অ্যারেগুলি সারি এবং কলামগুলির মধ্যে পার্থক্য করে না। এটা কি কারণ অ্যারে ম্যাট্রিকের চেয়ে টেনেসর হিসাবে ভাবা হয়? জো যেমন উল্লেখ করেছে, ম্যাট্রিক্স ক্লাসটি 2-মিমি হ'ল বিষয়টি বেশ সীমাবদ্ধ। এই জাতীয় নকশার পিছনে কী ভাবছে, মাতলাব / অষ্টভরের মতো একক ম্যাট্রিক্স শ্রেণি কেন নেই?
ইলেকশোবি

আমার ধারণা মূল বিষয়টি হ'ল অজগরটিতে .*বনাম '*' সিন্ট্যাক্স বনাম ম্যাট্রিক্সের গুণিতক উপাদান নেই। যদি এরকমটি থাকে তবে এগুলি সব থেকে সহজ হবে যদিও আমি অবাক হয়েছি তারা *মৌলিক বুদ্ধি নয় ম্যাট্রিক্সের গুণকে বোঝায়।
চার্লি পার্কার

উত্তর:


127

ব্যবহারটি এড়ানোর মূল কারণ matrixক্লাসটি হ'ল) ক) এটি সহজাতভাবে দ্বিমাত্রিক এবং খ) একটি "সাধারণ" ন্যূনতম অ্যারের তুলনায় অতিরিক্ত ওভারহেড রয়েছে। যদি আপনি যা করছেন তা লিনিয়ার বীজগণিত হয়, তবে সর্বদা, ম্যাট্রিক্স শ্রেণিটি নির্দ্বিধায় ব্যবহার করুন ... ব্যক্তিগতভাবে আমি এটির চেয়ে বেশি সমস্যা মনে করি, যদিও এর চেয়ে বেশি।

অ্যারেগুলির জন্য (পাইথন 3.5 এর পূর্বে) এর dotপরিবর্তে ব্যবহার করুন matrixmultiply

যেমন

import numpy as np
x = np.arange(9).reshape((3,3))
y = np.arange(3)

print np.dot(x,y)

বা নাম্পির নতুন সংস্করণগুলিতে সহজভাবে ব্যবহার করুন x.dot(y)

ব্যক্তিগতভাবে, আমি *ম্যাট্রিক্সের গুণাকে বোঝানো অপারেটরের চেয়ে অনেক বেশি পঠনযোগ্য বলে মনে করি ...

পাইথন ৩.৩ এ অ্যারেগুলির জন্য, ব্যবহার করুন x @ y


10
এটি অপঠনযোগ্য যখন আপনার গুণের একটি স্ট্যাক থাকে, উদাহরণস্বরূপ x ' A' * A x।
ইলেকশোবি

14
@ ইলেক্সহোবি - যদিও x.T.dot(A.T).dot(A).dot(x)এটি অপঠনযোগ্য নয়, তবে প্রতিটি তার নিজেরই নয়। আপনি যদি প্রাথমিকভাবে ম্যাট্রিক্সের গুণকটি করেন তবে সব উপায়ে ব্যবহার করুন numpy.matrix!
জো কিংটন

7
যাইহোক, কেন ম্যাট্রিক্স গুণকে "ডট" বলা হয়? কোন অর্থে এটি একটি বিন্দু পণ্য?
amcnabb

8
@ এমসিএনএবিবি - পাঠ্যপুস্তকগুলিতে ম্যাট্রিক্সের গুণটিকে কখনও কখনও "ডট পণ্য" হিসাবে উল্লেখ করা হয় (সেই বইগুলিতে, আপনি যে ডট পণ্যটির কথা ভাবছেন তাকে "স্কেলার পণ্য" বা "স্কেলার ডট পণ্য" বলা হয়)। স্কেলার ডট পণ্যটি কেবল দুটি ভেক্টরের কেবলমাত্র ম্যাট্রিক্সের গুণ, তবে সাধারণভাবে ম্যাট্রিক্সের গুণনের অর্থ "ডট" ব্যবহার করা খুব বেশি কিছু নয়। অন্তত আমার অভিজ্ঞতার তুলনায় গণিতের চেয়ে ইঞ্জিনিয়ারিং এবং বিজ্ঞান পাঠগুলিতে সেই বিশেষ চিহ্নটি (?) বেশি দেখা যায়। numpy.matrixmultiplyটাইপ করা শক্ত হওয়ায় বেশিরভাগ ক্ষেত্রে নপিতে এর বিস্তার ale
জো কিংটন

7
@ এমএএনএএনএবিবি মূল বিষয়টি হ'ল বিন্দু অস্পষ্টতা ছাড়াই স্বেচ্ছাসেবী মাত্রিকতায় সাধারণীকরণ করে । এটি numpy.dotম্যাট্রিক্সের গুণকে সমান করে তোলে । আপনি যদি স্বরলিপিটি সত্যিই অপছন্দ করেন তবে matrixক্লাসটি ব্যবহার করুন ।
হেনরি গোমারসাল

80

NumPy ম্যাট্রিকেসে অপারেশন বনাম NumPy অ্যারেতে অপারেশনের জন্য গুরুত্বপূর্ণ জিনিসগুলি হ'ল :

  • নুমপি ম্যাট্রিক্স নুমপি অ্যারের একটি সাবক্লাস

  • NumPy অ্যারের ক্রিয়াকলাপ উপাদান-ভিত্তিক (একবার সম্প্রচারের জন্য গণনা করা হয়)

  • NumPy ম্যাট্রিক্স অপারেশনগুলি লিনিয়ার বীজগণিতের সাধারণ নিয়ম অনুসরণ করে

উদাহরণস্বরূপ কয়েকটি কোড স্নিপেটস:

>>> from numpy import linalg as LA
>>> import numpy as NP

>>> a1 = NP.matrix("4 3 5; 6 7 8; 1 3 13; 7 21 9")
>>> a1
matrix([[ 4,  3,  5],
        [ 6,  7,  8],
        [ 1,  3, 13],
        [ 7, 21,  9]])

>>> a2 = NP.matrix("7 8 15; 5 3 11; 7 4 9; 6 15 4")
>>> a2
matrix([[ 7,  8, 15],
        [ 5,  3, 11],
        [ 7,  4,  9],
        [ 6, 15,  4]])

>>> a1.shape
(4, 3)

>>> a2.shape
(4, 3)

>>> a2t = a2.T
>>> a2t.shape
(3, 4)

>>> a1 * a2t         # same as NP.dot(a1, a2t) 
matrix([[127,  84,  85,  89],
        [218, 139, 142, 173],
        [226, 157, 136, 103],
        [352, 197, 214, 393]])

তবে এই অপারেশনগুলি ব্যর্থ হয় যদি এই দুটি NumPy ম্যাট্রিক্স অ্যারেতে রূপান্তরিত হয়:

>>> a1 = NP.array(a1)
>>> a2t = NP.array(a2t)

>>> a1 * a2t
Traceback (most recent call last):
   File "<pyshell#277>", line 1, in <module>
   a1 * a2t
   ValueError: operands could not be broadcast together with shapes (4,3) (3,4) 

যদিও এনপি.ডট সিনট্যাক্স ব্যবহার করে অ্যারে ব্যবহার করে ; এই অপারেশনগুলি ম্যাট্রিক্স গুণনের মতো কাজ করে:

>> NP.dot(a1, a2t)
array([[127,  84,  85,  89],
       [218, 139, 142, 173],
       [226, 157, 136, 103],
       [352, 197, 214, 393]])

সুতরাং আপনি কি কখনও NumPy ম্যাট্রিক্স প্রয়োজন? উদাহরণস্বরূপ, লিনিয়ার বীজগণিত গণনার জন্য কোনও NumPy অ্যারে যথেষ্ট হবে (আপনি যদি সঠিক বাক্য গঠনটি জানেন, অর্থাত NP.dot জানেন)?

নিয়মটি মনে হচ্ছে যে যদি প্রদত্ত লিনিয়ার বীজগণিত অপারেশনের সাথে যুক্তিগুলির (অ্যারেগুলি) আকারগুলি (এমএক্সএন) সামঞ্জস্যপূর্ণ হয় তবে আপনি ঠিক আছেন, নইলে নুমপি ছুড়ে ফেলে।

আমি কেবলমাত্র ব্যতিক্রমটি পেরেছি (সম্ভবত অন্যরাও রয়েছেন) ম্যাট্রিক্স বিপরীত গণনা করছে

নীচে স্নিপেটগুলি রয়েছে যেখানে আমি একটি শুদ্ধ লিনিয়ার বীজগণিত অপারেশন বলেছি (আসলে, নিম্পির লিনিয়ার বীজগণিত মডিউল থেকে) এবং একটি নুমপি অ্যারেতে পেরিয়েছি

একটি অ্যারের নির্ধারক :

>>> m = NP.random.randint(0, 10, 16).reshape(4, 4)
>>> m
array([[6, 2, 5, 2],
       [8, 5, 1, 6],
       [5, 9, 7, 5],
       [0, 5, 6, 7]])

>>> type(m)
<type 'numpy.ndarray'>

>>> md = LA.det(m)
>>> md
1772.9999999999995

ইগেনভেেক্টর / ইগেনভ্যালু জোড়া:

>>> LA.eig(m)
(array([ 19.703+0.j   ,   0.097+4.198j,   0.097-4.198j,   5.103+0.j   ]), 
array([[-0.374+0.j   , -0.091+0.278j, -0.091-0.278j, -0.574+0.j   ],
       [-0.446+0.j   ,  0.671+0.j   ,  0.671+0.j   , -0.084+0.j   ],
       [-0.654+0.j   , -0.239-0.476j, -0.239+0.476j, -0.181+0.j   ],
       [-0.484+0.j   , -0.387+0.178j, -0.387-0.178j,  0.794+0.j   ]]))

ম্যাট্রিক্স আদর্শ :

>>>> LA.norm(m)
22.0227

কিউআর কার্যকারিতা :

>>> LA.qr(a1)
(array([[ 0.5,  0.5,  0.5],
        [ 0.5,  0.5, -0.5],
        [ 0.5, -0.5,  0.5],
        [ 0.5, -0.5, -0.5]]), 
 array([[ 6.,  6.,  6.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]]))

ম্যাট্রিক্স র‌্যাঙ্ক :

>>> m = NP.random.rand(40).reshape(8, 5)
>>> m
array([[ 0.545,  0.459,  0.601,  0.34 ,  0.778],
       [ 0.799,  0.047,  0.699,  0.907,  0.381],
       [ 0.004,  0.136,  0.819,  0.647,  0.892],
       [ 0.062,  0.389,  0.183,  0.289,  0.809],
       [ 0.539,  0.213,  0.805,  0.61 ,  0.677],
       [ 0.269,  0.071,  0.377,  0.25 ,  0.692],
       [ 0.274,  0.206,  0.655,  0.062,  0.229],
       [ 0.397,  0.115,  0.083,  0.19 ,  0.701]])
>>> LA.matrix_rank(m)
5

ম্যাট্রিক্স শর্ত :

>>> a1 = NP.random.randint(1, 10, 12).reshape(4, 3)
>>> LA.cond(a1)
5.7093446189400954

বিপরীতে একটি নম্পপি ম্যাট্রিক্স প্রয়োজনযদিও:

>>> a1 = NP.matrix(a1)
>>> type(a1)
<class 'numpy.matrixlib.defmatrix.matrix'>

>>> a1.I
matrix([[ 0.028,  0.028,  0.028,  0.028],
        [ 0.028,  0.028,  0.028,  0.028],
        [ 0.028,  0.028,  0.028,  0.028]])
>>> a1 = NP.array(a1)
>>> a1.I

Traceback (most recent call last):
   File "<pyshell#230>", line 1, in <module>
   a1.I
   AttributeError: 'numpy.ndarray' object has no attribute 'I'

তবে মুর-পেনরোজ সিউডোইনভারসটি ঠিক কাজ করে বলে মনে হচ্ছে

>>> LA.pinv(m)
matrix([[ 0.314,  0.407, -1.008, -0.553,  0.131,  0.373,  0.217,  0.785],
        [ 1.393,  0.084, -0.605,  1.777, -0.054, -1.658,  0.069, -1.203],
        [-0.042, -0.355,  0.494, -0.729,  0.292,  0.252,  1.079, -0.432],
        [-0.18 ,  1.068,  0.396,  0.895, -0.003, -0.896, -1.115, -0.666],
        [-0.224, -0.479,  0.303, -0.079, -0.066,  0.872, -0.175,  0.901]])

>>> m = NP.array(m)

>>> LA.pinv(m)
array([[ 0.314,  0.407, -1.008, -0.553,  0.131,  0.373,  0.217,  0.785],
       [ 1.393,  0.084, -0.605,  1.777, -0.054, -1.658,  0.069, -1.203],
       [-0.042, -0.355,  0.494, -0.729,  0.292,  0.252,  1.079, -0.432],
       [-0.18 ,  1.068,  0.396,  0.895, -0.003, -0.896, -1.115, -0.666],
       [-0.224, -0.479,  0.303, -0.079, -0.066,  0.872, -0.175,  0.901]])

3
mInv = NP.linalg.inv (মি) একটি অ্যারের বিপরীত গণনা করে
db1234

এখানে লক্ষণীয় একটি গুরুত্বপূর্ণ বিষয় হ'ল * উপাদান অনুসারে গুণফল, বিন্দুটি হ'ল ম্যাট্রিক্সের গুণ। দয়া করে স্ট্যাকওভারফ্লো.com
মিন ট্রায়েট

আইএমপি দ্রষ্টব্য: অ্যারে এর পক্ষে নপি ম্যাট্রিকগুলি এড়ানো উচিত। ডকুমেন্টেশন থেকে নোট -> "লিনিয়ার বীজগণিতের জন্য এমনকি এই শ্রেণিটি ব্যবহার করার আর সুপারিশ করা হয় না Instead পরিবর্তে নিয়মিত অ্যারে ব্যবহার করুন The ভবিষ্যতে বর্গটি সরানো যেতে পারে।" আরও দেখুন stackoverflow.com/a/61156350/6043669
HopeKing

21

3.5 তে, পাইথন শেষ পর্যন্ত একটি ম্যাট্রিক্স গুণিত অপারেটর পেল । বাক্য গঠনটি হ'ল a @ b


2
ধন্যবাদ! হ্যাঁ, খুশী হয়ে দেখেছি যে আমিই একা নন যে অনুভব করেন যে বর্তমানের স্বরলিপিটি অপঠনযোগ্য।
ইলেকশোবি

15

এমন একটি পরিস্থিতি রয়েছে যেখানে ম্যাট্রিক্সের সাথে ডিল করার সাথে সাথে অ্যারে নিয়ে কাজ করার সময় ডট অপারেটর বিভিন্ন উত্তর দেবে। উদাহরণস্বরূপ, ধরুন নিম্নলিখিতগুলি:

>>> a=numpy.array([1, 2, 3])
>>> b=numpy.array([1, 2, 3])

এগুলি ম্যাট্রিকগুলিতে রূপান্তর করতে দেয়:

>>> am=numpy.mat(a)
>>> bm=numpy.mat(b)

এখন, আমরা দুটি ক্ষেত্রে পৃথক আউটপুট দেখতে পাচ্ছি:

>>> print numpy.dot(a.T, b)
14
>>> print am.T*bm
[[1.  2.  3.]
 [2.  4.  6.]
 [3.  6.  9.]]

নির্দিষ্ট করে বলতে গেলে, * উপাদান-ভিত্তিক গুণ, ডট হ'ল ম্যাট্রিক্সের গুণ x দয়া করে দেখুন স্ট্যাকওভারফ্লো.com
মিন ট্রায়েট

এটি কারণ একটি ন্যালি অ্যারে, এ টি == এ হিসাবে ট্রান্সপোজ কিছুই করেন না।
patapouf_ai

আপনি যদি = np.array ([[1], [2], [3]]) এ লিখেন, তবে numpy.dot (এ, খ) আপনাকে একই দেওয়া উচিত। ম্যাটিক্স এবং অ্যারের মধ্যে পার্থক্য বিন্দুতে নয় ট্রান্সপোজে।
patapouf_ai

অথবা প্রকৃতপক্ষে, আপনি যদি একটি = numpy.array ([[1,2,3]]) লিখেন তবে এটিটি সত্যিই স্থানান্তরিত হবে এবং সবকিছু ম্যাট্রিকের মতো কাজ করবে।
patapouf_ai

8

Http://docs.scipy.org/doc/scipy/references/tutorial/linalg.html থেকে রেফারেন্স

..., numpy.matrix শ্রেণীর ব্যবহারকে নিরুৎসাহিত করা হয়েছে , যেহেতু এটি 2D numpy.ndarray অবজেক্টের সাথে সম্পন্ন করা যায় না এমন কোনও কিছুই যুক্ত করে না এবং কোন শ্রেণিটি ব্যবহার করা হচ্ছে তা নিয়ে বিভ্রান্তির সৃষ্টি হতে পারে । উদাহরণ স্বরূপ,

>>> import numpy as np
>>> from scipy import linalg
>>> A = np.array([[1,2],[3,4]])
>>> A
    array([[1, 2],
           [3, 4]])
>>> linalg.inv(A)
array([[-2. ,  1. ],
      [ 1.5, -0.5]])
>>> b = np.array([[5,6]]) #2D array
>>> b
array([[5, 6]])
>>> b.T
array([[5],
      [6]])
>>> A*b #not matrix multiplication!
array([[ 5, 12],
      [15, 24]])
>>> A.dot(b.T) #matrix multiplication
array([[17],
      [39]])
>>> b = np.array([5,6]) #1D array
>>> b
array([5, 6])
>>> b.T  #not matrix transpose!
array([5, 6])
>>> A.dot(b)  #does not matter for multiplication
array([17, 39])

স্কিপি.লিনালগ অপারেশনগুলি numpy.matrix বা 2D numpy.ndarray অবজেক্টগুলিতে সমানভাবে প্রয়োগ করা যেতে পারে ।


7

এই কৌশল আপনি যা খুঁজছেন তা হতে পারে। এটি এক ধরণের সাধারণ অপারেটর ওভারলোড।

এরপরে আপনি প্রস্তাবিত ইনফিক্স শ্রেণীর মতো কিছু ব্যবহার করতে পারেন:

a = np.random.rand(3,4)
b = np.random.rand(4,3)
x = Infix(lambda x,y: np.dot(x,y))
c = a |x| b

5

পিইপি 465 এর প্রাসঙ্গিক উক্তি - @ পেট্র-ভিক্টোরিয়েন দ্বারা উল্লিখিত ম্যাট্রিক্স গুণনের জন্য একটি উত্সর্গীকৃত ইনফিক্স অপারেটর ওপিতে যে সমস্যাটি আসছিল তা স্পষ্ট করে:

[...] নাম্পি বিভিন্ন __mul__পদ্ধতি সহ দুটি ভিন্ন ধরণের সরবরাহ করে। জন্য numpy.ndarrayবস্তু, *সঞ্চালিত elementwise গুণ এবং ম্যাট্রিক্স গুণ একটি ফাংশন কল ব্যবহার করা আবশ্যক ( numpy.dot)। জন্য numpy.matrixবস্তু, *সঞ্চালিত গুণ ম্যাট্রিক্স, এবং elementwise গুণ ফাংশন সিনট্যাক্স প্রয়োজন। রাইটিং কোড ব্যবহার numpy.ndarrayকরে সূক্ষ্ম কাজ করে । রাইটিং কোড ব্যবহার করেnumpy.matrix করেও সূক্ষ্ম কাজ । তবে আমরা এই দুটি টুকরো কোড একসাথে সংহত করার চেষ্টা করার সাথে সাথেই সমস্যা শুরু হয়। কোড যা একটি আশা করে ndarrayএবং একটি matrix, বা তদ্বিপরীত হয়, ক্র্যাশ বা ভুল ফলাফল ফিরে আসতে পারে

@ইনফিক্স অপারেটরের পরিচয় পাইথন ম্যাট্রিক্স কোডকে একীকরণ এবং সহজ করতে সহায়তা করবে।


1

ফাংশন ম্যাটমুল (যেহেতু নম্পি ১.১০.১.১) উভয় প্রকারের জন্য সূক্ষ্মভাবে কাজ করে এবং ফলাফলটি একটি ন্পু ম্যাট্রিক্স শ্রেণীর হিসাবে ফলাফল:

import numpy as np

A = np.mat('1 2 3; 4 5 6; 7 8 9; 10 11 12')
B = np.array(np.mat('1 1 1 1; 1 1 1 1; 1 1 1 1'))
print (A, type(A))
print (B, type(B))

C = np.matmul(A, B)
print (C, type(C))

আউটপুট:

(matrix([[ 1,  2,  3],
        [ 4,  5,  6],
        [ 7,  8,  9],
        [10, 11, 12]]), <class 'numpy.matrixlib.defmatrix.matrix'>)
(array([[1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1]]), <type 'numpy.ndarray'>)
(matrix([[ 6,  6,  6,  6],
        [15, 15, 15, 15],
        [24, 24, 24, 24],
        [33, 33, 33, 33]]), <class 'numpy.matrixlib.defmatrix.matrix'>)

যেহেতু পাইথন 3.5 হিসাবে উল্লিখিত গোড়ার দিকে একটি নতুন ম্যাট্রিক্স গুণ অপারেটর ব্যবহার করতে পারেন @মত

C = A @ B

এবং উপরের মত একই ফলাফল পেতে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.