الوحدة 2 · أساسيات pandas
الاختيار باستخدام loc و iloc
18 دقراءة 3 دتمرين Python
الدرس في لمحة
اختر الأعمدة بالأقواس المربعة، ثم اختر صفوفًا وأعمدة محدّدة بـ .loc (بالتسمية) و .iloc (بالموقع)، واعرف أيّهما تستخدم بعد الترتيب أو التصفية.
لا فيديو هنا، بل الشيء الحقيقي: درس مكتوب وأمثلة قابلة للتشغيل واختبار وتدريب.
يسأل مدير المنتجات في Cartwheel: “بكم نبيع مطحنة القهوة، المنتج 7؟” و"أرني أغلى خمسة منتجات مع تكاليفها". كلاهما مسألة اختيار: من جدول، استخرج هذه الصفوف وهذه الأعمدة بالضبط. تعطيك pandas أداتين دقيقتين لذلك، .loc و.iloc، ومعظم ارتباك المبتدئين يأتي من الخلط بينهما. القاعدة قصيرة: .loc تستخدم التسميات، و.iloc تستخدم المواقع.
الأعمدة أولًا
الأقواس المربعة على DataFrame تختار الأعمدة:
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] تسميات الصفوف أولًا، ثم تسميات الأعمدة:
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:
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”.
لماذا يهم الفرق: الترتيب
رتّب المنتجات بحسب السعر، فتفترق الأداتان:
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كعملية بحث.