دليل المصفوفات في بايثون

دليل المصفوفات في بايثون

المُقدّمة

تخيل أن لديك قائمة تشغيل لأغانيك المفضلة على هاتفك. قائمة التشغيل هذه عبارة عن قائمة يتم فيها وضع كل أغنية بترتيب معين. يمكنك تشغيل الأغنية الأولى، والانتقال إلى الثانية، والانتقال إلى الخامسة، وما إلى ذلك. تشبه قائمة التشغيل هذه إلى حد كبير المصفوفة في برمجة الكمبيوتر.

تعتبر المصفوفات واحدة من أكثر هياكل البيانات الأساسية والأكثر استخدامًا.

في الأساس، المصفوفة هي طريقة منظمة لتخزين عناصر متعددة (مثل الأرقام أو الأحرف أو حتى المصفوفات الأخرى) بترتيب معين، ويمكنك الوصول بسرعة إلى أي عنصر أو تعديله أو إزالته إذا كنت تعرف موضعه (الفهرس).

في هذا الدليل، سنقدم لك نظرة شاملة حول بنية بيانات المصفوفة. في البداية، سنلقي نظرة على ماهية المصفوفات وما هي خصائصها الرئيسية. سننتقل بعد ذلك إلى عالم بايثون، ونستكشف كيفية تنفيذ المصفوفات ومعالجتها وتطبيقها في سيناريوهات العالم الحقيقي.

فهم بنية بيانات الصفيف

تعد المصفوفات من أقدم وأهم هياكل البيانات المستخدمة في علوم الكمبيوتر والبرمجة. إن بساطتها، جنبًا إلى جنب مع كفاءتها في عمليات معينة، تجعلها موضوعًا أساسيًا لأي شخص يتعمق في مجال إدارة البيانات ومعالجتها.

المصفوفة عبارة عن مجموعة من العناصر، عادةً ما تكون من نفس النوعيه، مخزن في مواقع الذاكرة المتجاورة.

يسمح هذا التخزين المتجاور للمصفوفات بتوفير وصول دائم إلى أي عنصر، بالنظر إلى فهرسه. كل عنصر في المصفوفة يسمى العنصر، ويتم تحديد موضع العنصر في المصفوفة من خلاله مؤشروالتي عادة يبدأ من الصفر.

على سبيل المثال، النظر في مجموعة من الأعداد الصحيحة: [10, 20, 30, 40, 50]. هنا العنصر 20 لديه فهرس 1:

فهرسة صفيف بايثون

هناك متعددة مزايا استخدام المصفوفات لتخزين بياناتنا. على سبيل المثال، نظرًا لتخطيط ذاكرتها، تسمح المصفوفات بذلك يا (1) التعقيد الزمني (الثابت) عند الوصول إلى عنصر من خلال فهرسه. وهذا مفيد بشكل خاص عندما نحتاج إلى الوصول العشوائي إلى العناصر. بالإضافة إلى ذلك، يتم تخزين المصفوفات في مواقع الذاكرة المتجاورة، مما قد يؤدي إلى تحسين منطقة ذاكرة التخزين المؤقت وتحسين الأداء العام في عمليات معينة. هناك ميزة أخرى ملحوظة لاستخدام المصفوفات وهي أنه نظرًا لأن المصفوفات لها حجم ثابت بمجرد الإعلان عنها، فمن الأسهل إدارة الذاكرة وتجنب التجاوزات غير المتوقعة أو أخطاء نفاد الذاكرة.

ملاحظات: المصفوفات مفيدة بشكل خاص في السيناريوهات التي يكون فيها حجم المجموعة معروف مسبقًا ويظل ثابتًاأو عندما يكون الوصول العشوائي أكثر تكرارًا من عمليات الإدراج والحذف.

على الجانب الآخر، تأتي المصفوفات مع مجموعتها الخاصة من القيود. أحد القيود الأساسية للمصفوفات التقليدية هو حجم ثابت. بمجرد إنشاء المصفوفة، لا يمكن تغيير حجمها. يمكن أن يؤدي هذا إلى مشاكل مثل إهدار الذاكرة (إذا كان المصفوفة كبيرة جدًا) أو الحاجة إلى تغيير الحجم (إذا كانت المصفوفة صغيرة جدًا). بالإضافة إلى ذلك، فإن إدراج أو حذف عنصر في منتصف المصفوفة يتطلب نقل العناصر، مما يؤدي إلى O (ن) التعقيد الزمني لهذه العمليات.

لتلخيص كل هذا، دعونا نوضح الخصائص الرئيسية للمصفوفات باستخدام مثال قائمة تشغيل الأغنية من بداية هذا الدليل. المصفوفة هي بنية البيانات التي:

  • تمت فهرسته: تمامًا كما تحتوي كل أغنية في قائمة التشغيل الخاصة بك على رقم (1، 2، 3، ...)، فإن كل عنصر في المصفوفة له فهرس. ولكن، في معظم لغات البرمجة، يبدأ الفهرس عند 0. لذا، العنصر الأول يكون عند الفهرس 0، والثاني عند الفهرس 1، وهكذا.

  • لديه حجم ثابت: عندما تقوم بإنشاء قائمة تشغيل لعشرة أغانٍ مثلاً، لا يمكنك إضافة الأغنية الحادية عشرة دون إزالة واحدة أولاً. وبالمثل، فإن المصفوفات لها حجم ثابت. بمجرد إنشاء مصفوفة بحجم معين، لا يمكنك إضافة عناصر أكثر من سعتها.

  • متجانس: جميع الأغاني الموجودة في قائمة التشغيل الخاصة بك هي مقطوعات موسيقية. وبالمثل، جميع العناصر في المصفوفة هي من نفس النوع. إذا كان لديك مصفوفة من الأعداد الصحيحة، فلن تتمكن فجأة من تخزين سلسلة نصية فيها.

  • لديه الوصول المباشر: إذا كنت ترغب في الاستماع إلى الأغنية السابعة في قائمة التشغيل الخاصة بك، فيمكنك الانتقال إليها مباشرة. وبالمثل، مع المصفوفات، يمكنك الوصول فورًا إلى أي عنصر إذا كنت تعرف فهرسه.

  • الذاكرة المتجاورة: هذا أكثر تقنية قليلاً. عندما يتم إنشاء مصفوفة في ذاكرة الكمبيوتر، فإنها تشغل كتلة مستمرة من الذاكرة. فكر في الأمر كصف من الخزائن المتجاورة في المدرسة. كل خزانة بجوار الأخرى، دون وجود فجوات بينهما.

بايثون والمصفوفات

تقدم بايثون، المعروفة بمرونتها وسهولة استخدامها، طرقًا متعددة للعمل مع المصفوفات. على الرغم من أن لغة Python لا تحتوي على بنية بيانات مصفوفة أصلية مثل بعض اللغات الأخرى، إلا أنها توفر بدائل قوية يمكن أن تعمل بشكل مماثل وحتى توفر إمكانات موسعة.

للوهلة الأولى، قائمة بايثون قد يبدو مرادفًا للمصفوفة، ولكن هناك اختلافات دقيقة وفروق دقيقة يجب مراعاتها:

قائمة مجموعة
بنية بيانات بايثون مدمجة ليست لغة أصلية في بايثون - فهي تأتي من الوحدة النمطية "array".
الحجم الديناميكي حجم ثابت (محدد مسبقًا).
يمكن أن تحتوي على عناصر من أنواع بيانات مختلفة احتفظ بعناصر من نفس النوع
توفير مجموعة من الأساليب المضمنة للتلاعب تحتاج إلى استيراد وحدات خارجية
O(1) التعقيد الزمني لعمليات الوصول O(1) التعقيد الزمني لعمليات الوصول
تستهلك المزيد من الذاكرة المزيد من كفاءة الذاكرة

بالنظر إلى هذا الجدول، من الطبيعي أن نسأل - "متى تستخدم أي؟". حسنًا، إذا كنت بحاجة إلى مجموعة يمكن أن تنمو أو تتقلص ديناميكيًا ويمكن أن تحتوي على أنواع بيانات مختلطة، فإن قائمة بايثون هي الحل الأمثل. ومع ذلك، بالنسبة للسيناريوهات التي تتطلب مجموعة أكثر كفاءة في الذاكرة مع عناصر من نفس النوع، قد تفكر في استخدام Python array الوحدة النمطية أو المكتبات الخارجية مثل NumPy.

مجموعة الوحدة النمطية في بايثون

عندما يفكر معظم المطورين في المصفوفات في بايثون، فإنهم غالبًا ما يفكرون في القوائم. ومع ذلك، تقدم بايثون بنية مصفوفة أكثر تخصصًا من خلال بنيتها المدمجة array وحدة. توفر هذه الوحدة تخزينًا موفرًا للمساحة لأنواع البيانات الأساسية على نمط C في Python.

في حين أن قوائم بايثون متعددة الاستخدامات بشكل لا يصدق ويمكنها تخزين أي نوع من الكائنات، إلا أنها قد تكون مبالغة في بعض الأحيان، خاصة عندما تحتاج فقط إلى تخزين مجموعة من أنواع البيانات الأساسية، مثل الأعداد الصحيحة أو الأعداد العشرية. ال array توفر الوحدة طريقة لإنشاء صفائف أكثر كفاءة في الذاكرة من قوائم أنواع بيانات محددة.

إنشاء مصفوفة

لاستخدام ال array الوحدة، تحتاج أولاً إلى استيرادها:

from array import array

بمجرد الاستيراد، يمكنك إنشاء مصفوفة باستخدام ملف array() البناء:

arr = array('i', [1, 2, 3, 4, 5])
print(arr)

هنا، و 'i' تشير الوسيطة إلى أن المصفوفة ستخزن موقعة الأعداد الصحيحة. هناك العديد من رموز النوع الأخرى المتاحة، مثل 'f' للعوامات و 'd' للزوجي.

الوصول إلى العناصر وتعديلها

يمكنك الوصول إلى العناصر وتعديلها في مصفوفة تمامًا كما تفعل مع القائمة:

print(arr[2]) 

والآن، دعونا نعدل العنصر عن طريق تغيير قيمته إلى 6:

arr[2] = 6
print(arr) 

طرق المصفوفة

array توفر الوحدة عدة طرق لمعالجة المصفوفات:

  • append() - إضافة عنصر إلى نهاية المصفوفة:

    arr.append(7)
    print(arr) 
  • extend() - إلحاق العناصر القابلة للتكرار في النهاية:

    arr.extend([8, 9])
    print(arr) 
  • pop() - إزالة العنصر وإعادته إلى الموضع المحدد:

    arr.pop(2)
    print(arr) 
  • remove(): إزالة التواجد الأول للقيمة المحددة:

    arr.remove(2)
    print(arr) 
  • reverse(): يعكس ترتيب المصفوفة:

    arr.reverse()
    print(arr) 

ملحوظة: هناك طرق أكثر مما ذكرناه هنا. الرجوع إلى وثائق بايثون الرسمية لرؤية قائمة بجميع الطرق المتاحة في array وحدة.

وعلى الرغم من أن array توفر الوحدة طريقة أكثر كفاءة في الذاكرة لتخزين أنواع البيانات الأساسية، ومن الضروري أن تتذكرها القيود. على عكس القوائم، المصفوفات متجانس. وهذا يعني أن جميع العناصر في المصفوفة يجب أن تكون من نفس النوع. أيضا، يمكنك تخزين فقط أنواع البيانات الأساسية على نمط C في المصفوفات. إذا كنت بحاجة إلى تخزين كائنات مخصصة أو أنواع أخرى من لغة Python، فستحتاج إلى استخدام قائمة أو بنية بيانات أخرى.

مصفوفات NumPy

NumPy، اختصار لـ Numerical Python، هي حزمة أساسية للحسابات الرقمية في Python. واحدة من ميزاته الأساسية هي قوتها كائن صفيف N-الأبعاد، والذي يوفر عمليات سريعة على المصفوفات، بما في ذلك المعالجة الرياضية والمنطقية ومعالجة الأشكال والمزيد.

تعد صفائف NumPy أكثر تنوعًا من صفائف Python المدمجة array وهي عنصر أساسي في علوم البيانات ومشاريع التعلم الآلي.

لماذا نستخدم مصفوفات NumPy؟

أول ما يتبادر إلى الذهن هو أداء. يتم تنفيذ مصفوفات NumPy في لغة C وتسمح بتخزين الذاكرة بكفاءة وعمليات أسرع بفضل الخوارزميات المحسنة وفوائد تخزين الذاكرة المتجاورة.

على الرغم من أن القوائم والمصفوفات المضمنة في لغة Python أحادية البعد، إلا أن مصفوفات NumPy يمكن أن تكون كذلك متعدد الأبعادمما يجعلها مثالية لتمثيل المصفوفات أو الموترات.

تحقق من دليلنا العملي العملي لتعلم Git ، مع أفضل الممارسات ، والمعايير المقبولة في الصناعة ، وورقة الغش المضمنة. توقف عن أوامر Googling Git وفي الواقع تعلم ذلك!

وأخيرا، يوفر NumPy مجموعة واسعة من الوظائف للعمل على هذه المصفوفات، بدءًا من العمليات الحسابية الأساسية وحتى العمليات الرياضية المتقدمة، وإعادة التشكيل، والتقسيم، والمزيد.

ملحوظة: عندما تعرف حجم البيانات مسبقًا، فإن التخصيص المسبق للذاكرة للمصفوفات (خاصة في NumPy) يمكن أن يؤدي إلى تحسينات في الأداء.

إنشاء مصفوفة NumPy

لاستخدام NumPy، عليك أولاً تثبيته (pip install numpy) ثم قم باستيراده:

import numpy as np

بمجرد الاستيراد، يمكنك إنشاء مصفوفة NumPy باستخدام الملف array() وظيفة:

arr = np.array([1, 2, 3, 4, 5])
print(arr) 

يمكنك أيضًا إنشاء صفائف متعددة الأبعاد:

matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(matrix)

هذا سوف يعطينا:

[[1 2 3] [4 5 6] [7 8 9]]

إلى جانب هذه الطرق الأساسية التي يمكننا من خلالها إنشاء المصفوفات، يوفر لنا NumPy طرقًا ذكية أخرى يمكننا من خلالها إنشاء المصفوفات. واحد منها هو arange() طريقة. يقوم بإنشاء صفائف ذات قيم متزايدة بانتظام:

arr = np.arange(10)
print(arr) 

واحد آخر هو linspace() الطريقة، التي تنشئ صفائف بعدد محدد من العناصر، متباعدة بالتساوي بين قيم البداية والنهاية المحددة:

even_space = np.linspace(0, 1, 5)
print(even_space) 

الوصول إلى العناصر وتعديلها

يعد الوصول إلى العناصر وتعديلها في مصفوفة NumPy أمرًا بديهيًا:

print(arr[2]) arr[2] = 6
print(arr) 

تفعل الشيء نفسه تقريبًا بالنسبة للمصفوفات متعددة الأبعاد:

print(matrix[1, 2]) matrix[1, 2] = 10
print(matrix)

سيتم تغيير قيمة العنصر في الصف الثاني (index 1) والعمود الثالث (index 2):

[[1 2 3] [4 5 20] [7 8 9]]

تغيير شكل المصفوفة

يقدم NumPy العديد من الوظائف والأساليب للتعامل مع المصفوفات وتشغيلها. على سبيل المثال، يمكنك استخدام reshape() طريقة ل تغيير شكل المصفوفة. لنفترض أن لدينا مصفوفة بسيطة:

import numpy as np arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
print("Original Array:")
print(arr) 

ونريد إعادة تشكيلها إلى مصفوفة 3×4. كل ما عليك فعله هو استخدام reshape() الطريقة بالأبعاد المطلوبة التي تم تمريرها كوسائط:


reshaped_arr = arr.reshape(3, 4)
print("Reshaped Array (3x4):")
print(reshaped_arr)

سيؤدي هذا إلى:

Reshaped Array (3x4):
[[ 1 2 3 4] [ 5 6 7 8] [ 9 10 11 12]]

ضرب المصفوفة

numpy.dot() يتم استخدام الطريقة ل مصفوفة الضرب. تقوم بإرجاع المنتج النقطي لصفيفين. بالنسبة للمصفوفات أحادية البعد، فهي منتج داخلي من المصفوفات. بالنسبة للمصفوفات ثنائية الأبعاد، فهي تعادل مصفوفة الضرب، وبالنسبة لـ ND، فهو أ منتج المبلغ على المحور الأخير من المصفوفة الأولى والثاني إلى الأخير من المصفوفة الثانية.

دعونا نرى كيف يعمل. أولاً، دعونا نحسب حاصل الضرب النقطي لمصفوفتين أحاديتي الأبعاد (المنتج الداخلي للمتجهات):

import numpy as np vec1 = np.array([1, 2, 3])
vec2 = np.array([4, 5, 6])
dot_product_1d = np.dot(vec1, vec2) print("Dot product of two 1-D arrays:")
print(dot_product_1d) 

سيؤدي هذا إلى:

Dot product of two 1-D arrays:
32

32 هو، في الواقع، المنتج الداخلي للمصفوفتين - (14 + 25+3*6). بعد ذلك، يمكننا إجراء ضرب المصفوفات لمصفوفتين ثنائي الأبعاد:


mat1 = np.array([[1, 2], [3, 4]])
mat2 = np.array([[2, 0], [1, 3]])
matrix_product = np.dot(mat1, mat2) print("Matrix multiplication of two 2-D arrays:")
print(matrix_product) 

والتي ستعطينا:

Matrix multiplication of two 2-D arrays:
[[ 4 6] [10 12]]

تعد مصفوفات NumPy خطوة مهمة للأمام مقارنة بالقوائم المضمنة في Python و array وحدة، وخاصة بالنسبة للحسابات العلمية والرياضية. إن كفاءتها، جنبًا إلى جنب مع الوظائف الغنية التي توفرها مكتبة NumPy، تجعلها أداة لا غنى عنها لأي شخص يتطلع إلى إجراء عمليات عددية في Python.

وفي الختام

لقد أثبتت المصفوفات، وهي حجر الزاوية في علوم الكمبيوتر والبرمجة، قيمتها مرارًا وتكرارًا عبر مختلف التطبيقات والمجالات. في بايثون، يتم استخدام بنية البيانات الأساسية هذه، من خلال تجسيداتها المختلفة مثل القوائم، array توفر الوحدة النمطية ومصفوفات NumPy القوية للمطورين مزيجًا من الكفاءة والتنوع والبساطة.

خلال هذا الدليل، انتقلنا من المفاهيم الأساسية للمصفوفات إلى تطبيقاتها العملية في لغة بايثون. لقد رأينا كيف توفر المصفوفات، بطبيعتها المتجاورة في الذاكرة، أوقات وصول سريعة، وكيف توفر قوائم بايثون الديناميكية طبقة إضافية من المرونة. لقد بحثنا أيضًا في عالم NumPy المتخصص، حيث تتحول المصفوفات إلى أدوات قوية للحساب الرقمي.

الطابع الزمني:

اكثر من ستاكابوز