مقارنة بين Iloc و Loc في Pandas: دليل مع أمثلة

أحد تلك الأمور المزعجة التي نحاول جميعًا فهمها عندما نتعلم Pandas هو التمييز بين .loc و .iloc.

لنضع حدًا لهذا الالتباس ونوضح الفرق بين هذين الأسلوبين. سأقدم العديد من الأمثلة، وآمل أن يكون التمييز أكثر وضوحًا بنهاية هذه المدونة.

ما هي .loc و .iloc في Pandas؟

كل من .loc و .iloc هما سمتان أساسيتان لإطارات البيانات في Pandas، وكلاهما يستخدمان لتحديد مجموعات فرعية محددة من البيانات. الغرض منهما هو الوصول إلى جزء معين من إطار البيانات وتمكين تلاعبه بدلاً من الوصول إلى الإطار بأكمله. 

ميزة

.loc

.iloc

الصيغة

df.loc[row_indexer, column_indexer]

df.iloc[row_indexer, column_indexer]

طريقة الفهرسة

الفهرسة بناءً على التسمية

الفهرسة بناءً على الموقع

تستخدم للإشارة

تسميات الصفوف والأعمدة

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

كما يمكننا رؤية من الجدول، يبدو البناء متشابهًا للغاية. الاختلاف يكمن في كيفية استخدام وسيطات row_indexer و column_indexer. هذا يرجع إلى أن الطريقتين تقدمان نهجين مختلفين للفهرسة: بينما تقوم .loc بالفهرسة بناءً على تسميات الصفوف، فإن .iloc يأخذ الفهرس الرقمي للصفوف والأعمدة كوسيطات.

لنفحص كلتا الطريقتين بتفصيل، نبدأ بـ .loc.

باستخدام .loc: الاختيار بواسطة التسميات

لتوضيح المفاهيم، دعنا نفترض قاعدة بيانات العملاء الافتراضية الممثلة بواسطة هذه الإطار البيانات يسمى df، مع معرف العميل الذي يمثل الفهرس الصف index:

معرف العميل

الاسم

البلد

المنطقة

العمر

C123

جون دو

الولايات المتحدة

أمريكا الشمالية

67

C234

بيتر مولر

ألمانيا

أوروبا

51

C345

علي خان

باكستان

آسيا

19

C456

ماريا غونزاليس

المكسيك

شمال أمريكا

26

C567

ديفيد لي

الصين

آسيا

40

هناك أربع طرق رئيسية لتحديد الصفوف باستخدام .loc. وتشمل:

  • تحديد صف واحد
  • تحديد صفوف متعددة
  • تحديد شريحة من الصفوف
  • تحديد الصفوف بشكل شرطي

تحديد صف واحد باستخدام .loc

لتحديد صف واحد، نستخدم تسمية الصف الذي نريد استرجاعه كـ row_indexer. وبالتالي، تبدو الصيغة كالتالي: df.loc['row_label']. لنستخدم هذا لعرض جميع المعلومات عن عميلنا علي خان:

df.loc['C345']

C345

 

اسم

علي خان

البلد

باكستان

المنطقة

آسيا

العمر

19

اختيار عدة صفوف باستخدام .loc

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

السطر df.loc[['row_label_1', 'row_label_2']] سيعيد الصفين من إطار البيانات df المحددين في القائمة. لنفترض أننا أردنا معرفة المعلومات ليس فقط عن علي خان ولكن أيضًا عن ديفيد لي:

df.loc[['C345', 'C567']]

معرف العميل

الاسم

الدولة

المنطقة

العمر

C345

علي خان

باكستان

آسيا

19

C567

ديفيد لي

الصين

آسيا

40

اختيار شريحة من الصفوف باستخدام .loc

يمكننا تحديد مجموعة من الصفوف عن طريق تمرير علامات الصف الأولى والأخيرة مع علامة الاقتسام بينهما: df.loc['علامة_بداية_الصف':'علامة_نهاية_الصف']. يمكننا عرض أول أربع صفوف في إطار البيانات الخاص بنا بهذه الطريقة:

df.loc['C123' : 'C456']

معرّف العميل

الاسم

البلد

المنطقة

تاريخ التسجيل

C123

جون دو

الولايات المتحدة

أمريكا الشمالية

67

C234

بيتر مولر

ألمانيا

أوروبا

51

C345

علي خان

باكستان

آسيا

19

C456

ماريا غونزاليس

المكسيك

أمريكا الشمالية

26

هناك أمران يجب أن تضعهما في الاعتبار هنا:

  1. يتضمن الناتج الصف المحدد في row_label_end. وهذا يختلف في .iloc، والذي سنتناوله لاحقًا.
  2. نستخدم زوجًا واحدًا فقط من الأقواس المربعة، على الرغم من أننا نريد استرجاع عدة صفوف. نحن لا نستخدم قائمة لتحديد الصفوف المختلفة، لذا فإن استخدام قوسي مربعين سيؤدي إلى SyntaxError.

اختيار الصفوف بشكل شرطي باستخدام .loc

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

البنية النحوية المقابلة هي df.loc[conditional_expression]، حيث يكون conditional_expression عبارة عن بيان حول القيم المسموح بها في عمود معين.

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

df.loc[df['Region'] != 'Asia']

معرف العميل

الاسم

البلد

المنطقة

العمر

C123

جون دو

الولايات المتحدة

أمريكا الشمالية

67

C234

بترا مولر

ألمانيا

أوروبا

51

C456

ماريا غونزاليس

المكسيك

أمريكا الشمالية

26

اختيار عمود واحد باستخدام .loc

لاختيار الأعمدة، نحتاج إلى تحديد وسيط column_indexer، الذي يأتي بعد وسيط row_indexer. إذا أردنا فقط تحديد column_indexer، نحتاج إلى وضع علامة على أننا نريد إرجاع جميع الصفوف وتصفية الأعمدة فقط. دعونا نرى كيف يمكننا فعل ذلك!

يمكن اختيار عمود واحد عن طريق تحديد column_indexer مع علامة العمود المعني. لاسترجاع جميع الصفوف، نحتاج إلى تحديد row_indexer مع نقطتين بسيطتين. نصل إلى بناء جملة يبدو كالتالي: df.loc[:, 'اسم العمود'].

دعونا نعرض اسم كل عميل:

df.loc[:, 'Name']

معرف العميل

اسم

C123

جون دو

C234

بترا مولر

C345

علي خان

C456

ماريا غونزاليس

C567

ديفيد لي

اختيار عدة أعمدة باستخدام .loc

يشبه اختيار عدة صفوف، نحتاج إلى تمرير قائمة من تسميات الأعمدة إذا أردنا إرجاع عدة أعمدة من DataFrame التي لا تتبع بالضرورة بعضها البعض بالترتيب: df.loc[:, [col_label_1, 'col_label_2']].

افترض أننا أردنا إضافة جميع أعمار العملاء إلى مخرجاتنا الأخيرة، سيكون الأمر على النحو التالي:

df.loc[:, ['Name', 'Age']]

معرّف العميل

الاسم

العمر

C123

جون دو

67

C234

بترا مولر

51

C345

علي خان

19

C456

ماريا غونزاليس

26

C567

ديفيد لي

40

تحديد شريحة من الأعمدة باستخدام .loc

استخدام نقطتين بين تسميات عمودين سيحدد جميع الأعمدة في النطاق بين العمودين المحددين. يشمل العمود النهائي، مما يعني أن العمود المسمى col_end سيتم اختياره أيضًا في الصيغة القياسية، وهي كما يلي: df.loc[:, 'col_start':'col_end'].

إذا كنا مهتمين بـ الاسم، الدولة، و المنطقة لعملائنا، يمكن أن تكون سطر الشيفرة لدينا:

df.loc[:, 'Name':'Region']

معرف العميل

الاسم

الدولة

المنطقة

C123

جون دو

الولايات المتحدة

أمريكا الشمالية

C234

بترا مولر

ألمانيا

أوروبا

C345

علي خان

باكستان

آسيا

C456

ماريا غونزاليس

المكسيك

أمريكا الشمالية

C567

ديفيد لي

الصين

آسيا

اختيار الصفوف والأعمدة معًا باستخدام .loc

من الممكن أيضًا تحديد كل من row_indexer وcolumn_indexer. يمكن استخدام ذلك لاسترجاع قطعة واحدة من المعلومات، مما يعني خلية واحدة من DataFrame. للقيام بذلك، نقوم بتحديد صف واحد وعمود واحد باستخدام الصيغة df.loc['row_label', 'column_name'] .

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

إليك مثال واحد على إرجاع Name وCountry وRegion لكل عميل بعمر Age يزيد عن 30:

df.loc[df['Age'] > 30, 'Name':'Region']

معرف العميل

الاسم

الدولة

المنطقة

C123

جون دو

الولايات المتحدة

أمريكا الشمالية

C234

بترا مولر

ألمانيا

أوروبا

C567

ديفيد لي

الصين

آسيا

استخدام .iloc: الاختيار بواسطة موضع العدد

.iloc يختار حسب الموضع بدلاً من التسمية. هذه هي الصيغة القياسية لاستخدام .iloc: df.iloc[row_indexer, column_indexer]. هناك أمران خاصان يجب الانتباه لهما:

  • العد بدءًا من 0: الصف الأول والعمود لهما الفهرس 0، والثاني له الفهرس 1، وهكذا.
  • حصريّة قيمة نهاية النطاق: عند استخدام شريحة، فإن الصف أو العمود المحدد خلف النقطتين لا يتم تضمينه في الاختيار.

اختيار صف واحد باستخدام .iloc

يمكن اختيار صف واحد باستخدام العدد الصحيح الذي يمثل رقم فهرس الصف كـ row_indexer. لا نحتاج إلى علامات اقتباس لأننا ندخل رقمًا صحيحًا وليس سلسلة تسمية كما فعلنا مع .loc. لإرجاع الصف الأول من DataFrame يسمى df، أدخل df.iloc[0].

في مثال DataFrame الخاص بنا، هذه السطر من الشيفرة يعيد معلومات جون دو:

df.iloc[0]

C123

 

Name

John Doe

Country

United States

Region

North America

Age

67

اختيار عدة صفوف باستخدام .iloc

يعمل اختيار عدة صفوف في .iloc كما يفعل في .loc – ندخل أرقام فهرس الصفوف في قائمة بأقواس مربعة. يبدو الصيغة بهذا الشكل: df.iloc[[0، 3، 4]].

يمكن رؤية الناتج المتوافق في جدول العملاء لدينا أدناه:

df.iloc[[0, 3, 4]]

Customer ID

Name

Country

Region

Age

C123

John Doe

الولايات المتحدة

أمريكا الشمالية

67

C456

ماريا غونزاليس

المكسيك

أمريكا الشمالية

26

C567

ديفيد لي

الصين

آسيا

40

تحديد شريحة من الصفوف باستخدام .iloc

لتحديد شريحة من الصفوف، نستخدم علامة الاقتباس بين رقمي فهرس الصفوف المحددين. الآن، علينا أن نولي اهتمامًا للحصرية المذكورة سابقًا. 

يمكننا أن نأخذ السطر df.iloc[1:4] كمثال لتوضيح هذا المفهوم. يعني الرقم المؤشري 1 الصف الثاني، لذا تبدأ شريحتنا من هناك. يمثل الرقم المؤشري 4 الصف الخامس – لكن نظرًا لأن .iloc لا يشمل الاختيار الشريحة، سيتم إرجاع الصفوف الموجودة حتى قبل هذا الصف الأخير. لذلك، سيتم إرجاع الصف الثاني والثالث والرابع. 

دعونا نثبت أن السطر يعمل كما يجب:

df.iloc[1:4]

معرف العميل

الاسم

الدولة

المنطقة

العمر

C234

بيترا مولر

ألمانيا

أوروبا

51

C345

علي خان

باكستان

آسيا

19

C456

ماريا غونزاليس

المكسيك

أمريكا الشمالية

26

اختيار عمود واحد باستخدام .iloc

تتبع منطق اختيار الأعمدة باستخدام .iloc ما تعلمناه حتى الآن. دعنا نرى كيف يعمل مع الأعمدة الفردية، والأعمدة المتعددة وشرائح الأعمدة.

تمامًا كما هو الحال مع .loc، من المهم تحديد row_indexer قبل أن نتمكن من الانتقال إلى column_indexer. لاسترداد قيم العمود الثالث من df لكل صف، ندخل df.iloc[:, 2].

نظرًا لأن Region هو العمود الثالث في إطار البيانات الخاص بنا، فسيتم استرجاعه نتيجة لهذا السطر من الكود:

df.iloc[:, 2]

معرف العميل

المنطقة

C123

أمريكا الشمالية

C234

أوروبا

C345

آسيا

C456

أمريكا الشمالية

C567

آسيا

اختيار أعمدة متعددة باستخدام .iloc

لاختيار أعمدة متعددة ليست بالضرورة متتالية، يمكننا مرة أخرى إدخال قائمة تحتوي على أعداد صحيحة كـ column_indexer. السطر df.iloc[:, [0, 3]] يُرجع كلا من العمود الأول والرابع.

في حالتنا، المعلومات المعروضة هي الاسم بالإضافة إلى العمر لكل عميل:

df.iloc[:, [0, 3]]

رقم العميل

الاسم

العمر

C123

جون دو

67

C234

بيتر مولر

51

C345

علي خان

19

C456

ماريا غونزاليس

26

C567

دايفيد لي

40

اختيار شريحة من الأعمدة باستخدام .iloc

لتحديد الشريحة باستخدام .iloc، تتبع منطق column_indexer منطق row_indexer. العمود الممثل بالعدد بعد الفاصلة لا يتم تضمينه في الناتج. لاسترداد العمود الثاني والثالث، يجب أن يكون شكل الكود كالتالي: df.iloc[:, 1:3].

يُعيد السطر أدناه جميع المعلومات الجغرافية التي لدينا حول عملائنا:

df.iloc[:, 1:3]

رقم العميل

الدولة

المنطقة

C123

الولايات المتحدة

أمريكا الشمالية

C234

ألمانيا

أوروبا

C345

باكستان

آسيا

C456

المكسيك

أمريكا الشمالية

C567

الصين

آسيا

اختيار الصفوف والأعمدة معاً باستخدام .iloc

يمكننا تجميع ما تعلمناه عن .iloc لدمج اختيار الصفوف والأعمدة. مرة أخرى، من الممكن إرجاع خلية واحدة أو إطار بيانات فرعي. لإرجاع الخلية الوحيدة عند تقاطع الصف 3 والعمود 4، ندخل df.iloc[2, 3].

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

هذا المثال الأخير يعرض البلد، المنطقة والعمر للصف الأول والثاني والخامس في إطار بياناتنا:

df.iloc[[0,1,4], 1:4]

معرف العميل

البلد

المنطقة

العمر

C123

الولايات المتحدة

شمال أمريكا

67

C234

ألمانيا

أوروبا

51

C567

الصين

آسيا

40

.iloc مقابل .loc: متى يجب استخدام كل منهما

بشكل عام، هناك قاعدة بسيطة تعتمد على فهمك للبيانات:

  • استخدم .loc عندما تعرف التسميات (الأسماء) للصفوف/الأعمدة.
  • استخدم .iloc عندما تعرف مواقع الأعداد الصحيحة للصفوف/الأعمدة.

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

السيناريوهات التي تفضل .loc

السيناريوهات التي تفضل .iloc

يحتوي DataFrame الخاص بك على أسماء فهرس/أعمدة ذات معنى.

أنت تقوم بالتكرار عبر الصفوف/الأعمدة حسب موقعها.

تحتاج إلى تصفية بناءً على شروط تتعلق بقيم الأعمدة.

أسماء الفهرس/الأعمدة ليست ذات صلة بمهمتك.

خطأ في المفتاح، خطأ في الاسم، وخطأ في الفهرس مع .loc و .iloc

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

بالإضافة إلى ذلك، من المهم دائمًا استخدام علامات الاقتباس للتسميات المحددة باستخدام .loc. نسيانها سيؤدي إلى إرجاع NameError.

يمكن أن يحدث خطأ IndexError عند استخدام .iloc إذا حددنا موضعًا عدديًا خارج النطاق الصالح لمؤشرات DataFrame لدينا. يحدث هذا عندما لا يوجد الفهرس الذي تحاول الوصول إليه، إما لأنه يتجاوز عدد الصفوف أو الأعمدة في DataFrame الخاص بك أو لأنه قيمة سالبة. لتجنب هذا الخطأ، تحقق من أبعاد DataFrame الخاص بك واستخدم قيم فهرس مناسبة ضمن النطاق الصالح.

خاتمة

آمل أن تكون هذه المدونة قد كانت مفيدة وأن يكون الفارق بين .loc و .iloc واضحًا الآن. للتعرف على المزيد، إليك بعض الخطوات الجيدة التالية:

Source:
https://www.datacamp.com/tutorial/loc-vs-iloc