إضافة عناصر إلى مصفوفات NumPy بكفاءة
توفر مكتبة NumPy، وهي حجر الزاوية في نظام الحوسبة العلمية في بايثون، كائنات مصفوفة قوية متعددة الأبعاد. تقدم هذه المصفوفات مزايا أداء كبيرة مقارنة بقوائم بايثون القياسية، ولكن إضافة العناصر مباشرة ليست سهلة أو فعالة كما قد يتوقع المرء. يستعرض هذا البرنامج التعليمي بدائل فعالة لإضافة عناصر إلى مصفوفات NumPy.
جدول المحتويات
- مقدمة
- لماذا تجنب الإضافة المباشرة؟
- التخصيص المسبق
- الدمج
- التكديس الرأسي والأفقي
- التعبير القائم على القائمة وإنشاء المصفوفة
- اختيار الطريقة المناسبة
- خاتمة
مقدمة
صُممت مصفوفات NumPy للعمليات العددية الفعالة. يساهم حجمها الثابت بشكل كبير في هذه الكفاءة. على عكس قوائم بايثون، التي تعيد تغيير حجمها ديناميكيًا، فإن محاولة إضافة عناصر مباشرة إلى مصفوفة NumPy باستخدام طرق مشابهة لـ append()
في القائمة يؤدي إلى خطأ. ذلك لأن تغيير الحجم يستلزم إنشاء مصفوفة جديدة تمامًا، ونسخ البيانات القديمة، ثم إضافة العنصر الجديد – وهي عملية مكلفة من الناحية الحسابية، خاصةً بالنسبة للمصفوفات الكبيرة والإضافات المتكررة.
لماذا تجنب الإضافة المباشرة؟
إن إضافة العناصر مباشرة إلى مصفوفات NumPy غير فعالة لأنها تنطوي على إنشاء مصفوفة متكرر ونسخ البيانات. يؤدي هذا إلى تدهور كبير في الأداء، خاصة عند التعامل مع مجموعات بيانات كبيرة أو عمليات إضافة متكررة. تتفوق تكلفة تخصيص الذاكرة ونقل البيانات بكثير على فائدة الإضافة البسيطة.
التخصيص المسبق
غالباً ما يكون النهج الأكثر فعالية هو تخصيص مصفوفة مسبقًا بالحجم النهائي المطلوب، ثم ملؤها بشكل متكرر. هذا يتجنب إنشاء المصفوفة المتكرر المتأصل في الإضافة المتكررة.
import numpy as np
size = 1000
arr = np.empty(size, dtype=int) # تحديد dtype لتحسين الأداء
for i in range(size):
arr[i] = i * 2 #ملء بعض القيم
print(arr)
الدمج
تقوم دالة numpy.concatenate
بدمج المصفوفات الموجودة بكفاءة على طول محور موجود. هذا مثالي عندما يكون لديك مصفوفات متعددة تريد دمجها.
import numpy as np
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
arr_combined = np.concatenate((arr1, arr2))
print(arr_combined) # الإخراج: [1 2 3 4 5 6]
arr3 = np.array([[1,2],[3,4]])
arr4 = np.array([[5,6],[7,8]])
arr_combined_2d = np.concatenate((arr3,arr4), axis=0) #axis=0 للتكديس الرأسي، axis=1 للتكديس الأفقي
print(arr_combined_2d)
التكديس الرأسي والأفقي
لتكديس المصفوفات رأسيًا (صفًا بعد صف) وأفقيًا (عمودًا بعد عمود)، توفر numpy.vstack
و numpy.hstack
وظائف ملائمة.
import numpy as np
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
arr_vstack = np.vstack((arr1, arr2)) # تكديس رأسي
arr_hstack = np.hstack((arr1, arr2)) # تكديس أفقي
print("التكديس الرأسي:n", arr_vstack)
print("nالتكديس الأفقي:n", arr_hstack)
التعبير القائم على القائمة وإنشاء المصفوفة
لبناء مصفوفات من العناصر المتكررة، يمكن أن يكون التعبير القائم على القائمة مع numpy.array
موجزًا وفعالًا.
import numpy as np
arr = np.array([i**2 for i in range(10)])
print(arr)
اختيار الطريقة المناسبة
تعتمد الطريقة المثلى على حالة الاستخدام الخاصة بك:
- التخصيص المسبق: الأنسب لملء مصفوفة كبيرة بشكل متسلسل.
concatenate
: مثالي لدمج مصفوفات متعددة موجودة.vstack
/hstack
: ملائم للتكديس الرأسي أو الأفقي.- التعبير القائم على القائمة +
numpy.array
: موجز لإنشاء مصفوفات من العناصر المتكررة.
خاتمة
بينما لا تدعم مصفوفات NumPy الإضافة المباشرة مثل قوائم بايثون، إلا أن هناك بدائل فعالة. إن فهم هذه الطرق أمر بالغ الأهمية لكتابة شفرة عددية عالية الأداء. أعطي الأولوية للتخصيص المسبق كلما أمكن ذلك لتحقيق أقصى قدر من الكفاءة.