EduFlow
Python لتحليل البيانات
⁦0%⁩

الوحدة 2 · أساسيات pandas

الاختيار باستخدام loc و iloc

18 دقراءة 3 دتمرين Python

الدرس في لمحة

اختر الأعمدة بالأقواس المربعة، ثم اختر صفوفًا وأعمدة محدّدة بـ ‎.loc (بالتسمية) و ‎.iloc (بالموقع)، واعرف أيّهما تستخدم بعد الترتيب أو التصفية.

  1. 1الأعمدة أولًا
  2. 2‎.loc: الاختيار بالتسمية
  3. 3‎.iloc: الاختيار بالموقع
  4. 4لماذا يهم الفرق: الترتيب

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

يسأل مدير المنتجات في Cartwheel: “بكم نبيع مطحنة القهوة، المنتج 7؟” و"أرني أغلى خمسة منتجات مع تكاليفها". كلاهما مسألة اختيار: من جدول، استخرج هذه الصفوف وهذه الأعمدة بالضبط. تعطيك pandas أداتين دقيقتين لذلك، .loc و.iloc، ومعظم ارتباك المبتدئين يأتي من الخلط بينهما. القاعدة قصيرة: .loc تستخدم التسميات، و.iloc تستخدم المواقع.

الأعمدة أولًا

الأقواس المربعة على DataFrame تختار الأعمدة:

Python
import pandas as pd

products = pd.read_csv("products.csv", index_col="product_id")
print(products["name"].head(3))                    # one column: a Series
print(products[["name", "unit_price"]].head(3))    # a list of columns: a DataFrame

جعل index_col="product_id" معرّف المنتج فهرسًا للصفوف بدلًا من 0 و1 و2 الافتراضية. هذا الاختيار وحده يجعل كل ما يلي يُقرأ بطبيعية: المنتج 7 هو الصف المسمّى 7. ومع DataFrame محمّل مسبقًا، تقوم products.set_index("product_id") بالشيء نفسه وتعيد DataFrame جديدًا.

سترى أيضًا products.unit_price في الدروس التعليمية. الوصول بالنقطة يعمل مع الأسماء البسيطة، لكنه يفشل مع الأسماء التي فيها مسافات، ويعيد بصمت شيئًا خاطئًا حين يتشارك عمود اسمه مع method في الـ DataFrame: عمود اسمه count أو size تحجبه الـ method التي تحمل الاسم نفسه. الأقواس المربعة تعمل دائمًا، فاجعلها خيارك الافتراضي.

الأقواس المزدوجة ليست خطأً كتابيًا. الزوج الخارجي هو الاختيار، والزوج الداخلي قائمة Python بأسماء الأعمدة. عمود واحد داخل قائمة يعطيك DataFrame مع ذلك.

‎.loc: الاختيار بالتسمية

تأخذ .loc[rows, columns] تسميات الصفوف أولًا، ثم تسميات الأعمدة:

Python
import pandas as pd

products = pd.read_csv("products.csv", index_col="product_id")
print(products.loc[7, "unit_price"])                       # one value
print(products.loc[7])                                     # one row, as a Series
print(products.loc[[11, 21, 37], ["name", "unit_price"]])  # chosen rows and columns
print(products.loc[1:3, "name":"unit_price"])              # label slices

القوائم تختار التسميات التي تذكرها بالضبط، وبالترتيب نفسه. والشرائح تأخذ نطاقًا من التسميات، وهذا هو الجزء الذي يجب أن تتذكّره: شرائح .loc تشمل التسمية الأخيرة. تعيد products.loc[1:3] المنتجات 1 و2 و3. وشريحة الأعمدة "name":"unit_price" تشمل unit_price بالمثل. يصبح هذا منطقيًا حين تفكّر بالتسميات: “من المنتج 1 إلى المنتج 3” تشمل المنتج 3.

اطلب تسمية غير موجودة، مثل products.loc[99]، فتحصل على KeyError: 99. هذه ميزة: المعرّف الخاطئ يجب أن يفشل بصوت عالٍ، لا أن يعيد نتيجة فارغة قد تلصقها في تقرير. وحين يكون غياب التسمية احتمالًا طبيعيًا، افحص أولًا بـ 99 in products.index، التي تعيد True أو False.

و.loc أيضًا هي الأداة الوحيدة التي تستخدمها لإسناد القيم، كما سترى في الدرس 2.5: products.loc[7, "unit_price"] = 135.45 تغيّر خلية واحدة بالضبط.

‎.iloc: الاختيار بالموقع

تتجاهل .iloc التسميات وتعدّ المواقع من 0، وشرائحها تستبعد النهاية، تمامًا مثل قوائم Python:

Python
import pandas as pd

products = pd.read_csv("products.csv", index_col="product_id")
print(products.iloc[0])            # first row, whatever its label
print(products.iloc[:3, :2])       # first three rows, first two columns
print(products.iloc[-1]["name"])   # last row's name

استخدم .iloc حين يكون الموقع هو ما تقصده: “الخمسة الأولى”، “الصف الأخير”، “كل صف ثانٍ”. واستخدم .loc حين تكون الهوية هي ما تقصده: “المنتج 7”، “العمود unit_price”.

جدول مرتّب بحسب السعر، تسميات فهرسه 21 و 22 و 41 و 1 بهذا الترتيب، ومواقعه من 0 إلى 3. loc[1] تشير إلى الصف المسمّى 1، الواقع في الموقع 3. و iloc[0] تشير إلى الصف في الموقع 0، وتسميته 21. الموقع التسمية الاسم (مرتّب بالسعر) 0 21 Standing Desk 140cm 1 22 Ergonomic Task Chair 2 41 Adjustable Dumbbells ... 1 Cast Iron Skillet 26cm .iloc[0] .loc[1]
‎.loc تجد الصفوف بالتسمية، و ‎.iloc بالموقع

لماذا يهم الفرق: الترتيب

رتّب المنتجات بحسب السعر، فتفترق الأداتان:

Python
import pandas as pd

products = pd.read_csv("products.csv", index_col="product_id")
by_price = products.sort_values("unit_price", ascending=False)
print(by_price.iloc[:3][["name", "unit_price"]])   # the three priciest
print(by_price.loc[1, "name"])                     # still the skillet

الترتيب ينقل الصفوف، لكن كل صف يحتفظ بتسميته. أصبحت by_price.iloc[0] الآن هي Standing Desk، أغلى منتج بسعر 449 دولارًا؛ بينما by_price.loc[1] ما زالت Cast Iron Skillet، أينما انتهى بها المطاف. والتصفية تتصرّف بالطريقة نفسها: بعد أن تحتفظ ببعض الصفوف فقط، تصبح في التسميات فجوات (1، 4، 9…)، بينما يُعاد ترقيم المواقع 0، 1، 2. وإذا أردت تسميات جديدة من 0 إلى n، فإن reset_index(drop=True) تعيدها لك.

في التمرين تجيب عن أسئلة مدير المنتجات باستخدام .loc و.iloc. وفي الدرس التالي تختار الصفوف بحسب شرط بدلًا من التسمية: “كل الطلبات التي تتجاوز 200 دولار”، “كل طلبات الويب في نوفمبر”.

أهم النقاط

  • df["col"] تعيد عمودًا واحدًا على هيئة Series؛ وdf[["a", "b"]] (قائمة داخل الأقواس) تعيد DataFrame.
  • .loc[rows, columns] تختار بالتسمية، والشرائح فيها تشمل التسمية الأخيرة.
  • .iloc[rows, columns] تختار بالموقع، والشرائح فيها تستبعد النهاية، تمامًا مثل قوائم Python.
  • بعد الترتيب تبقى التسميات ملتصقة بصفوفها، فتجد .loc المنتج نفسه، بينما تجد .iloc[0] أيًّا كان الصف الذي صار أولًا.
  • اجعل الفهرس شيئًا له معنى مثل product_id باستخدام index_col= أو set_index()، كي تُقرأ .loc كعملية بحث.

قراءات إضافية

تحقّق من فهمك

4 أسئلة

السؤال 1 من 4

فهرس products هو product_id (من 1 إلى 48). كم صفًا تعيد products.loc[1:5]؟

السؤال 2 من 4

رتّبت products بحسب السعر، الأعلى أولًا. أيّ تعبير يعيد صف المنتج الأغلى؟

السؤال 3 من 4

ماذا تعيد products[["name"]] مقارنةً بـ products["name"]؟

السؤال 4 من 4

أيّ سطر يعطيك سعر الوحدة للمنتج 7 في خطوة واحدة واضحة؟

تدريب

تمرين Python

أجب مدير المنتجات

حُمّل products مع product_id فهرسًا له. اجعل grinder_price سعر الوحدة للمنتج 7. واجعل subset المنتجات 11 و21 و37 مع العمودين name وunit_cost فقط، بهذا الترتيب. واجعل top5 أغلى خمسة منتجات بكل أعمدتها، الأغلى أولًا. واجعل cheapest_name اسم المنتج الأرخص.

ملفات البيانات: products.csv

import pandas as pd

products = pd.read_csv("products.csv", index_col="product_id")

# 1. Unit price of product 7 (a single number)
grinder_price = None

# 2. Rows for products 11, 21 and 37, with only the name and unit_cost columns
subset = None

# 3. The five most expensive products (all columns), most expensive first
top5 = None

# 4. The name of the cheapest product
cheapest_name = None
جارٍ تحميل المحرّر…

Ctrl/⌘ + Enter للتشغيل · يعمل في بيئة معزولة داخل متصفّحك. لا شيء يغادر جهازك.

(لا مخرجات)

الفحوص

  • grinder_price يساوي 129
  • subset فيه المنتجات 11 و21 و37 والعمودان name و unit_cost
  • top5 يحمل أعلى خمسة أسعار بترتيب تنازلي
  • top5 يحتفظ بكل الأعمدة
  • cheapest_name يساوي Jump Rope Pro