مكتبة Numpy – الخطوة الأولى في علم البيانات بلغة البايثون

يقدم المقال معلومات عن مكتبة Numpy في البايثون وكيفية تثبيتها والتعامل معها في معالجة البيانات

ابراهيم البحيصيمنذ 5 سنوات

الرابط الأصلي للمقال من مدونة بايثونات : مكتبة Numpy - الخطوة الأولى لعلم البيانات في البايثون

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

تتمثل هذه الأفضلية التي تُقدمها Numpy على ال Lists في أن المصفوفات في مكتبة Numpy سريعة في عمليات القراءة والكتابة وتُعتبر أكثر كفاءةً ومتانة.

في هذا المقال وفي إطار نشر المعرفة بلغة البرمجة البايثون باللغة العربية، نُقدم لكم هذا المقال الذي يشرح كيفية التعامل مع مكتبة Numpy.

في نهاية المقال سوف تحصل على المعرفة اللازمة ل:

  • تثبيت مكتبة Numpy.
  • إنشاء مصفوفة Numpy.
  • إستيراد وتصدير البيانات من/إلى المصفوفة إلى/من ملفات خارجية.
  • التعرف على خصائص المصفوفات في مكتبة Numpy.
  • إجراء العمليات الرياضية على المصفوفات.
  • إجراء عمليات Subsetting, Slicing, Indexing.
  • تغيير شكل المصفوفات.
  • الحصول على مساعدة من دوال متخصصة في مكتبة Numpy.
  • طَرْقْ المصفوفة, وإجراء عمليات الإضافة والحذف.

ويُقدم لك المقال أيضًا بعض الروابط المساعدة في تعلم مكتبة Numpy

ملاحظة/ يُفترض في هذا المقال أنك على دراية أساسية بفهوم المصفوفات (Arrays) ولغة البرمجة البايثون.

مصفوفة Numpy

يوجد بعض النقاط التي تتشابه فيها مصفوفة Numpy مع المصفوفة العادية List  في البايثون، ولكن يوجد فرق كبير في نفس الوقت.

تُعد مصفوفة Numpy أحد أهم تراكيب البيانات في مكتبة Numpy والتي سُميت بهذا الإسم إختصارًا لمصطلح Numerical Python. ومن المصطلح ندرك أن هذه المكتبة هي مكتبة متخصصة في الحوسبة العلمية بلغة البايثون، وتحتوي على تشكيلة متنوعة من الأدوات والتقنيات التي من الممكن ان تستخدمها لحل مشاكل رياضية في مجالي العلوم والهندسة. أحد أهم هذه الأدوات في المكتبة هي المصفوفة ذات الأبعاد المتعددة والكفاءة الفائقة (High Performance Multidimensional Array)، والتي تستطيع أن تُطبق عليها الكثير من الدوال الرياضية والعمليات الحسابية لتُعطيك القدرة على حل العديد من المشاكل.

تثبيت مكتبة Numpy

تثبيت مكتبة البايثون Numpy

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

أولا: بإستخدام Python Wheels

إتبع الخطوات التالية:

  • تأكد أن بيئة عمل البايثون مثبتة على جهازك, وإن لم تكن كذلك فتستطيع تثبيت البايثون منهنا.

  • تأكد من عمل أداة pip وأن البايثون مضافة في متغير PATH environment.

  • في شاشة cmd نفذ أمر pip install –upgrade pip لعمل تحديث ل pip.

  • من هنا قم بتنزيل ملف wheel الذي يناسب نسخة البايثون الموجودة لديك.

  • نفذ الأمر pip install numpy_wheel_file

  • إفتح مُفسر أوامر البايثون وقم بعمل إستيراد للمكتبة import numpy وفي حال لم تظهر لك أي رسالة خطأ، فأنت قمت بتثبيت المكتبة بنجاح, وتستطيع بعد ذلك البدء بالتعامل معها.

ثانيا: بإستخدام توزيعة بايثون Anaconda

للحصول على مكتبة Numpy بشكل سهل وسريع تستطيع تثبيت توزيعة Anaconda من هنا.

قد تتساءل, من ناحية واقعية مالذي يجعل هذا الخيار أسهل؟

الأمر الجيد في الحصول على البايثون بإستخدام توزيعة Anaconda هو أنك لن تقلق بخصوص تثبيت مكتبة Numpy بشكل منفصل او أي مكتبة لها علاقة بتحليل البيانات مثل Pandas  أو Scikit-learn.

إذا كنت جديدًا في عالم البايثون او البرمجة بشكل عام، فإنه من المريح جدًا أن تستخدم توزيعة بايثون Anaconda والتي تحتوي أكثر من 100 مكتبة جاهزة ومتخصصة في مجال علم البيانات، كما أنها معتمدة لدى الكثير من علماء تحليل البيانات.

أيضًا، فإن Anaconda تحتوي العديد من أدوات وبيئات التطوير المفتوحة المصدر مثل Jupyter و Spyder.

إختصارًا لوقتك، أنصحك بتثبيت Anaconda للتعامل مع مكتبة Numpy وغيرها من مكتبات تحليل البيانات, والانظلاق نحو علم البيانات الرائع.

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

الان، وبعد أن أتممنا تثبيت البايثون ومكتبة Numpy، فإنه قد حان وقت العمل.

حتى يتسنى لنا البدء بإنشاء المصفوفة، لابد علينا إستيراد المكتبة في ملف البايثون الذي نكتبه ( او في جلسة العمل على مفسر أوامر البايثون) بإستخدام أمر import numpy، ولكن يجب علينا أن نتبع أفضل الممارسات هنا، حيث يجب علينا أن تستورد مكتبة numpy باسم np. إذا فعلنا ذلك، سنجعل البايثونيين يفهمون الكود بطريقة أسهل وأسرع.

نستخدم دالة np.array لإنشاء المصفوفةكالتالي:

>> import numpy as np
>> arr = np.array([1,2,3,4,5,6])
>> print(arr)

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

بعض الطرق لإنشاء مصفوفات خاصة

لإنشاء مصفوفة ذات أبعاد 3X4  تكون جميع عناصرها من الرقم 1 نستخدم الدالة np.ones:

>> np.ones((3,4))

لإنشاء مصفوفة بنفس الأبعاد وتكون جميع عناصرها من الرقم 0 نستخدم دالة np.zeros :

>> np.zeros((3,4))

لإنشاء مصفوفة من صفين و 3 أعمدة وتكون جميع عناصرها من رقم نقوم بتحديده نستخدم دالة np.full :

>> np.full((2,3), 10)

للحصول على مصفوفة تبدأ من رقم معين وتنتهي بقيمة تسبق رقم آخر بمقدار مُعين نستخدم دالة np.arange :

>> np.arange(5,30,5)

للحصول على مصفوفة تبدأ برقم معين وتنتهي برقم اخر مع تحديد عدد عناصر المصفوفة بحيث يكون مدى قيمة عناصرها بين الرقمين نستخدم الدالة np.linespace :

>> np.linspace(1,5,5)

تستطيع بإستخدام مكتبة Numpy أن تُنشئ مصفوفة الوحدة/ المحايدة والتي تسمى باللغة الإنجليزية ب Identity Matrix، وذلك بإستخدام أحد الدوال np.eye او np.identity.

ملاحظة/ مصفوفة الوحدة هي مصفوفة مربعة تكون قيم العناصر القطرية فيها 1 والباقي 0.

إستيراد البيانات من ملفات خارجية

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

سنتعلم فيما يلي كيفية إستيراد البيانات من ملفات txt وحفظها في مصفوفة.

نستطيع أن نقوم بعملية جلب البيانات من ملف نصي بإستخدام أحد الدالتين np.loadtxt أو np.genfromtxt.

لنفترض أنه لديك ملف باسم data.txt ويحتوي على نص بالشكل التالي:

Table of
data
id      mobile      com

1       0555        0.2
2       9999        0.1
3       6565        0.2
4       888         0.2
5       74744       0.3

الأمر التالي يقوم بإستيراد هذه البيانات من الملف إلى بيئة العمل:

>> id, mobile, com = np.loadtxt(‘data.txt’,skiprows=2,unpack=True)

في الكود السابق، قمنا أولاً بإدخال إسم الملف (الموجود في نفس مسار جلسة العمل او ملف البايثون)، ثم قمنا بإدخال قيمة 2 للخاصية skiprows والتي معناها تجاهل اول سطرين من الملف (لانهم نصوص وليس أرقام)، وأخيرا حددنا خاصية ال unpack بحيث تكون مخرجات الدالة عبارة عن مصفوفات بعدد الأعمدة.

في حال كانت الأعمدة في الملف النصي مفصولة بفاصلة او تريد تحديد نوع البيانات، فيمكنك تحدد ذاك بإعداد الخاصية delimiter و dtype على الترتيب.

حفظ المصفوفات في ملف خارجي

هنا نعمل على تصدير البيانات الموجودة في المصفوفة إلى ملفات خارجية ولذلك نستخدام الدالة np.savetxt.

>> x = np.arange(0,5,0.5)
>> np.savetxt(‘test.txt’,x,delimiter = ‘,’)

وهذه ليست الطريقة الوحيدة لتصدير المصفوفات الى ملف نصي، يوجد دوال مثل save, savez, savez_compressed والتي لها أغراض مختلفة لنفس الهدف.

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

خصائص المصفوفات

الجدول التالي يسرد الخصائص التي تستطيع الإستعلام عنها لمصفوفة باسم arr.

شكل المصفوفة arr.shape
أبعاد المصفوفة arr.ndim
عدد عناصر المصفوفة arr.size
نوع البيانات arr.dtype
حجم عناصر المصفوفة المستخدم ب bytes arr.nbytes
حجم العنصر الواحد في المصفوفةب bytes arr.itemsize
معلومات المصفوفة الخاصة بالذاكرة arr.flags

 

الأن وبعد أن تعرفت على كيفية إنشاء مصفوفة Numpy إما بإستخدام دالة np.array او عن طريق np.loadtxt و np.genfromtxt فإنه حان الوقت للتعرف أكثر على مصفوفات Numpy وإجراء العمليات الرياضية عليها.

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

لن أتطرق في هذا المقال إلى هذه القيود والشروط بقدر ما سأركز على التعريف بالمكتبة في الجانب البرمجي.

العمليات الرياضية

تستطيع إجراء العمليات الرياضية (الجمع، الطرح، الضرب، القسمة، باقي القسمة) على المصفوفات بإستخدام الرموز المعروفة + , – , * , / , % على الترتيب.

بالإضافة إلى ذلك، فإن مكتبة Numpy تقدم لك إجراء نفس العمليات الرياضية السابقة بإستخدام دوال np.add, np.substract, np.multiply, np.divide, np.remainder.

كذلك تستطيع إجراء العمليات الرياضية المتقدمة على المصفوفات، مثل عملية الأس، والجذر التربيعي، والعمليات الجيبية (sin, cos) و log وعملية ضرب المصفوفات (dot multiply).

هنا ستجد كل العمليات الرياضية التي تستطيع إجراءها على مصفوفات مكتبة Numpy.

بالإضافة إلى العمليات الرياضية، فإنه من الجدير ذِكره أنه بإمكاننا أيضًا مقارنة عناصر المصفوفات ببعضها البعض بإستخدام عمليات المقارنة مثل ==  , < , > .

عند إستخدامنا لعمليات المقارنة السابقة, فإن ناتج العملية هو مصفوفة منطقية بنفس الشكل تحتوي على قيم منطقية (True, False) تُعبر عن نتيجة المقارنة لكل عنصر من المصفوفة الأولى مع العنصر الذي يقابله في المصفوفة الثانية.

>> import numpy as np
>> a = np.array([[1,2],[3,4]])
>> b = np.array([[2,1],[4,3]])
>> a == b

array([[False, False],

[False, False]], dtype=bool)

 

>> a > b

array([[False, True],

[False, True]], dtype=bool)

دالة np.array_equal تقوم أيضا بمقارنة مصفوفتين ولكن النتيجة إما True  او False بحيث لو كاد أحد عناصر المصفوفة الأولى لا يساوي العنصر الذي يقابله في المصفوفة الثانية فإن النتيجة تكون False، وهذا يَفترض أن يكون شكل المصفوفتين التي يتم مقارنتهم واحد.

>> np.array_equal(a,b)

False

بجانب عملية مقارنة مصفوفتين، لاحظ أننا نستطيع أن إجراء العمليات المنطقية مثل OR, AND, NOT على المصفوفات بإستخدام الدوال np.logical_or , np.logical_not, np.logical_and.

عمليات Subset, Slice, Index

بجانب إجراء العمليات الرياضية على المصفوفات، نستطيع أن نقوم بعملية إقتطاع لجزء معين من المصفوفة لإجراء بعض العمليات على هذا الجزء دون الجزء الباقي من المصفوفة، أو قد نحتاج للتعامل مع عناصر منفردة من المصفوفة. في هذه الحالة فنحن بحاجة لإجراء عمليات مثل subset, slice او index على المصفوفة.

إذا كنت قد تعاملت مع ال Lists في البايثون، فستكون لديك المعرفة لإجراء العمليات السابقة، أما إذا كنت جديدًا على هذا الأمر فعليك أن تعرف النقطتين الأساسيتين التاليتين:

أولا: لابد عليك أن تكتب إسم المصفوفة متبوعا ب [ ] لإخبار البايثون بأنك تقوم بإجراء أحد العمليات السابقة.

ثانيا: غالبًا، ستقوم بتمرير أرقام بين [ ] ولكن أيضا تستطيع أن تدخل : داخلها بجانب الأرقام أو دونها, وذلك لإخبار البايثون بالجزء الذي انت مهتم به من المصفوفة.

وبالمثال يتضح المقال.

>> import numpy as np
>> array1d = np.array([1,2,3,4,5,6])
>> array2d = np. array([[1, 2, 3, 4], [5, 6, 7, 8]])

عملية Subsetting:

للحصول على العنصر الأول من المصفوفة array1d:

>> print( array1d[ 0 ] )

1

للحصول على العنصر في الصف رقم 1 والعمود رقم 2 من المصفوفة array2d:


 

>> print( array2d[ 1 , 2 ])

7

عملية Slicing:

تعتبر هذه العملية مشابهة لعملية Subsetting ولكنها متقدمة أكثر, حيث هنا فأنت لا تتعامل مع عناصر في أماكن معينة, بل تحصل على نطاق او Regions من المصفوفة.

للحصول على أول ثلاثة عناصر من المصفوفة array1d:

>> print(array1d [ 0 : 3 ])

[1 2 3]

للحصول على عناصر الصف رقم 0 والصف رقم  1 من العمود رقم 1 من المصفوفة array2d:

>> print(array2d [ 0:2 , 1 ] )

[2 6]

عملية Indexing:

سنتكلم هنا فقط عن Boolean Indexing وليس Fancy Indexing.

للحصول على العناصر التي قيمتها أكبر من 3 في المصفوفة  array1d:

>> print( array1d[ array1d > 3 ] )

[4 5 6]

للحصول على العناصر الزوجية من المصفوفة array2d:

>> print( array2d[ array2d % 2 == 0 ] )

[2 4 6 8]

الحصول على مساعدة

نستطيع إستخدام دالة help للحصول على التوثيق الخاص بالدوال او المديولات او الخصائص التي نتعامل معها في البايثون.

ولكن مكتبة Numpy تُقدم لك حلولًا أخرى تساعدك في الحصول على مساعدة أو معلومات أكثر عن الكود التي تقوم بكتباته بإستخدام دالتي np.lookfor و np.info .

التعامل مع المصفوفات

منقول المصفوفة (Array Transpose)

بإفتراض أن لديك مصفوفة A ذات شكل 3 * 2 فإن ناتج منقول المصفوفة هو مصفوفة بنفس العناصر ولكن بترتيب مختلف حيث يتم جعل الصفوف أعمدة والأعمدة صفوف وبذلك يُصبح شكل منقول المصفوفـة A هو 2 * 3.

نستطيع الحصول على منقول المصفوفة بإستخدام الدالة np.transpose أو الخاصية T الموجودة للمصفوفة:

>> np.transpose( array2d )

array([[1, 5],

[2, 6],

[3, 7],

[4, 8]])

 

>> array2d.T

array([[1, 5],

[2, 6],

[3, 7],

[4, 8]])

ملاحظة/ المصفوفات ذات البعد الواحد لا تتأثر بدالة np.transpose ولا بالخاصية T وتعطيك نفس الدالة دون تغيير.

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

ذكرتُ في السابق أنه يُوجد بعض القيود التي يجب أخذها بعين الإعتبار عند إجراء بعض العمليات على المصفوفات، ومن هذه الشروط، توافق شكل مصفوفتين في عمليات مثل ضرب المصفوفات (Dot Multiplication).

ولكن ماذا سنفعل لو كانت لدينا مصفوفات غير متوافقة الشكل؟ في هذه الحالة يأتي دور العمليات التي تُغير شكل المصفوفة أو تُكبرها مثل دالة np.resize.

عند تمرير مصفوفة للدالة np.resize بالإضافة إلى الشكل المطلوب، وكانت المصفوفة الجديدة أكبر من الأصلية، فإن المصفوفة الناتجة سيتم ملؤها بشكل متتابع بقيم من نفس المصفوفة الأصلية حسب الترتيب والحاجة.

>> np.resize( array2d, (4,6))

array([[1, 2, 3, 4, 5, 6],

[7, 8, 1, 2, 3, 4],

[5, 6, 7, 8, 1, 2],

[3, 4, 5, 6, 7, 8]])

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

>> array2d.resize((4,6))

array([[1, 2, 3, 4, 5, 6],

[7, 8, 0, 0, 0, 0],

[0, 0, 0, 0, 0, 0],

[0, 0, 0, 0, 0, 0]])

بجانب عملية ال resize للمصفوفة، يُمكن تغيير شكل المصفوفة باستخدام دالة reshape وفي هذه الحالة لن يؤثر التغيير على عدد عناصر المصفوفة.

وللتوضيح أكثر, لنفترض وجود مصفوفة بشكل 3*4 فإن عدد عناصرها هو 12. تستطيع أن تستخدم دالة reshape لتغيير شكل الدالة بحيث تحافظ على 12 عنصر الخاصة بها، وبذلك تكون أشكال مثل 4*3 و 6*2 و 2*6 أشكالا مقبولة وإلا سيظهر لك خطأ في حال استخدمت شكلا اخر.

>> array2d.reshape((4,2))

array([[1, 2],

[3, 4],

[5, 6],

[7, 8]])

طرق المصفوفة

تعمل دالة ravel على “طرق” المصفوفة، حيث تُحول أي مصفوفة ذات بعد ثنائي أو أكثر إلى مصفوفة ذات بعد واحد.

>> array2d.ravel()

array([1, 2, 3, 4, 5, 6, 7, 8])

الإضافة على المصفوفة

عند إضافة عناصر إلى المصفوفة، فإن تلك العناصر تُضاف إلى آخر المصفوفة، وذلك يتم بإستخدام دالة np.append التي تجعل من الإضافة امرًا سهلاً في مصفوفات مكتبة Numpy.

لإضافة صف جديد

>> new_array = np.append( array2d, [[9,10,11,12]], axis = 0)
>> new_array

array([[ 1, 2, 3, 4],

[ 5, 6, 7, 8],

[ 9, 10, 11, 12]])

لإضافة عمود جديد

>> new_array = np.append(array2d,[[9],[10]],axis = 1)
>> new_array

array([[ 1, 2, 3, 4, 9],

[ 5, 6, 7, 8, 10]])

لاحظ أننا إستخدمنا عند الإضافة الخاصية axis والتي تُحدد مكان الإضافة، هل ستكون لصف أم عمود. (في المصفوفة ذات البعد الثنائي axis = 1 يعني العمود, axis = 0 يعني الصف).

للإضافة على المصفوفة في مكان محدد (ليس في آخرها) نستخدم الدالة np.insert بالطريقة التالية:

>> new_array = np.insert( array2d , (0,0) , 5, axis = 1)
>> new_array

array([[5, 5, 1, 2, 3, 4],

[5, 5, 5, 6, 7, 8]])

في المثال السابق, قمنا بإضافة عمود بقيمة 5 في المكان (0,0) والذي يمثل بداية المصفوفة.للحذف من مكان معين في المصفوفة, نستخدم الدالة np.delete بنفس المفهوم.

روابط للتعلم:

1- هنا ستجد ملف Numpy_Python_Cheat_Sheet يلخص لك معلومات مهمة عن مكتبة Numpy.

2- https://www.datacamp.com/community/blog/python-numpy-cheat-sheet#gs.0_T9D90

3- http://cs231n.github.io/python-numpy-tutorial

4- http://www.python-course.eu/numpy.php

5- https://www.datacamp.com/community/tutorials/python-numpy-tutorial#gs.Ereixfc

الرابط الأصلي للمقال من مدونة بايثونات : مكتبة Numpy - الخطوة الأولى لعلم البيانات في البايثون

كلمات دليلية: numpy python
5
إعجاب
21133
مشاهدات
0
مشاركة
2
متابع
متميز
محتوى رهيب

التعليقات (0)

لايوجد لديك حساب في عالم البرمجة؟

تحب تنضم لعالم البرمجة؟ وتنشئ عالمك الخاص، تنشر المقالات، الدورات، تشارك المبرمجين وتساعد الآخرين، اشترك الآن بخطوات يسيرة !