Amer Abdallah نشر 12 أغسطس 2021 أرسل تقرير نشر 12 أغسطس 2021 لدي مصفوفتان numpy الأولى: x هي (m ، n) والثانية: y متجه (n ، 1) عندما أحاول إتمام عملية الضرب كالتالي: x*y أحصل على الخطأ: ValueError: operands could not be broadcast together with shapes (97,2) (2,1) عندما يكون حجم المصفوفة x هو (7,2) وحجم المصفوفة y هو (2,1) فمن المفترض أن تتم عملية الضرب بدون مشكلة ويكون الناتج عبارة عن مصفوفة حجمها (7,1) لماذا يظهر الخطأ السابق؟ وكيف أقوم بعملية الضرب هنا؟ 1 اقتباس
1 Ali Haidar Ahmad نشر 12 أغسطس 2021 أرسل تقرير نشر 12 أغسطس 2021 (معدل) هذا صحيح يجب أن تتم العملية من دون مشاكل لأن شرط ضرب المصفوفتين محقق، لكن أنت تستخدم المعامل الخطأ لضرب المصفوفتين.فالمعامل * يستخدم لتطبيق عملية الضرب عنصر بعنصر أي eliment-wise أي يقوم بضرب العناصر المتقابلة من المصفوفتين وبالتالي يجب أن تكون المصفوفتين بأبعاد متطاااابقة بالطول والعرض. أما إذا أردت تنفيذ عملية الضرب العادي للمصفوفات فهنا يجب أن تستخدم التابع dot (ولاتخلط بينه وبين ال . فال . ليس لها علاقة بالجداء وإنما هي خاصة بال attribute واستخدامها هنا سيعطي خطأ): import numpy as np a = np.array([[2, 1],[2,4]]) b = np.array([[2, 1],[2,4]]) # ضرب عاددي print(a.dot(b)) """ [[ 6 6] [12 18]] """ # eliment-wise print(a * b) """ [[ 4 1] [ 4 16]] """ لكن مهلاً دعني أوضح معنى الخطأ هو يقول لك أنه فشل في تطبيق عملية تسمى "brodcast" وهي عملية يطبقها بايثون عندما تكون العملية المطلوبة غير قابلة للتطبيق (في حالتك لديك مصفوفتين بأبعاد مختلفة وتحاول تطبيق عملية ضرب عنصر بعنصر وهذا غير ممكن، لكن بايثون لاتستسلم بهذه السهولة، لذا يحاول جعل المصفوفة الصغيرة بنفس أبعاد الكبيرة لكي تتم العملية لكنه أيضاً يفشل لماذا؟ سأشرح هذا بعد قليل). حسناً ..بايثون تدعم مانسميه ال broadcast وهو مصطلح يشير إلى كيفية تعامل numpy مع المصفوفات ذات الأبعاد المختلفة أثناء العمليات الحسابية التي لها قيود معينة، يتم تطبيق broadcast للمصفوفة الأصغر لتتطابق مع المصفوفة الأكبر بحيث يكون لها شكل متوافق لتنفيذ العملية. وهذا أمر مفيد جداً في علوم تعلم الآلة. وبشكل أوضح أو أكثر دقة عندما تحاول تطبيق عملية (eliment-wise) ضرب أو طرح أو تطبيق أي عملية رياضية على مصفوفتين غير متوافقتين بالأبعاد فإن بايثون سيحاول جعل المصفوفتين متوافقتين لكي تتم العملية، حيث يقوم بنسخ وتكرار وتوسيع للمصفوفة الصغيرة بحيث تحقق شرط تطبيق العملية المطلوبة، وبشكل أدق ركز معي: لو كان لديك مصفوفة ابعادها (m,n) وقمت بجمعها او طرحها او ضربها او قسمتها على مصفوفة من الحجم (1 عمود و n سطر) سيتم نسخ المصفوفة الثانية m مرة ليصبح حجمها مثل حجم المصفوفة الأولى. وبشكل مشابه لو كان لديك مصفوفة بحجم m سطر و 1 عمود، سيتم نسخ هذه المصفوفة n مرة لتصبح بحجم الأولى أي (m,n) ومن ثم تطبيق العملية المرادة. ، مثال: import numpy as np a1 = np.array([2, 4, 3]) a1.shape # (3,) a2 = np.array([50, 2, 10]) a2.shape # (3,) # هنا مصفوفتين متوافقتين بالحجم لكن لايمكن ضربهما ضرب مصفوفات عادي لكن هنا يتم ضربهما عنصر بعنصر c = a1 * a2 print (c) #[350 4 180] مثال آخر: import numpy as np a1 = np.array([2, 4, 3]) a1.shape # (3,) a2 = 3 #brodcast هنا غير متطابقين ولا يتحقق شرط الجمع لكن يتم تنفيذ عملية c = a1 + a2 print(c) #[5 7 6] مثال: import numpy as np a1 = np.array([[1, 2, 3], [10, 2, 30]]) a2 = 4 C = a1 + a2 print(C) """ [[ 5 6 7] [14 6 34]] """ لكن لل brodcast شروط وهي أن المصفوفتين يجب أن تتطابق إحدى أبعادهما وإلا يفشل وهذا ماحدث معك. a = np.random.randn(97,2) b = np.random.randn(2,1) a*b #ValueError: operands could not be broadcast together with shapes (97,2) (2,1) تم التعديل في 12 أغسطس 2021 بواسطة Ali Haidar Ahmad 1 اقتباس
0 محمد أبو عواد نشر 12 أغسطس 2021 أرسل تقرير نشر 12 أغسطس 2021 يحصل هذا الخطأ لأنك تستخدم العملية الخاطئة, يجب أن تسخدم الدوت " . " لهذه العملية بينما عملية * تقوم بفعل أمر آخر, إذا كانت X و y من النوع numpy.matrix ، فيمكن استخدام علامة النجمة كضرب مصفوفة ولكن حاول الابتعاد عن numpy.matrix لأنها تعقد الامور بدل من تبسيطها, حاول تنفيذ الامر كالتالي x.y اقتباس
0 Ahmed Sharshar نشر 12 أغسطس 2021 أرسل تقرير نشر 12 أغسطس 2021 (معدل) هذه المشكلة تحدث بسبب شكل المصفوفات التي تريد ضربهما، دعنا نفهم كيف تتم ضرب المصفوفات. لضرب مصفوفتين يجب ان يكون عدد الاعمدة في المصفوفة الاولى يساوى عدد صفوف المصفوفة الثانية، حيث ان ترتيب الضرب يهم، كمثال لضرب مصفوفة ذات ابعاد (5,3) * (4,5) تنتج مصفوفة ذات ابعاد (4,3) حيث تمثل اول قيمه عدد الصفوف وهي هنا =4 والقيمة الثانية عدد الاعمدة وهي هنا 3. اما بالنسبة للمشكلة هنا تحديدا فهي بسبب استخدام الشكل * ، وهي تقوم بعملية ضرب المصفوفات فقط في حالة انها علي شكل numpy.matrix وبشكل عام تقوم العلامة * بعمل ضرب القيم سويا او ما يسمي element wise multiplication وهذا يجعل عملية الضرب المطلوبة غير ملاءمة لانة يجب ان تكون كلتا المصفوفتين من نفس الشكل تماما. لكن المطورين ابتعدوا عن هذا الشكل وعوضا عنها استخدموا العلامة . والتي تمثل dot product . فيمكنك هنا اما تحويل المصفوفتين الي Numpy.matrix وضربهما او استخدام x.y للضرب مباشرة. يمكنك كذلك استخدام numpy.dot، والتي تقوم بعملية الضرب المعتادة للمصفوفات، انظر المثال التالي: In [1]: import numpy In [2]: numpy.dot(numpy.ones([97, 2]), numpy.ones([2, 1])).shape Out[2]: (97, 1) تم التعديل في 12 أغسطس 2021 بواسطة Ahmed Sharshar 1 اقتباس
السؤال
Amer Abdallah
لدي مصفوفتان numpy الأولى: x هي (m ، n) والثانية: y متجه (n ، 1)
عندما أحاول إتمام عملية الضرب كالتالي:
أحصل على الخطأ:
عندما يكون حجم المصفوفة x هو (7,2) وحجم المصفوفة y هو (2,1) فمن المفترض أن تتم عملية الضرب بدون مشكلة ويكون الناتج عبارة عن مصفوفة حجمها (7,1)
لماذا يظهر الخطأ السابق؟ وكيف أقوم بعملية الضرب هنا؟
3 أجوبة على هذا السؤال
Recommended Posts
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.