انتقل إلى المحتوى الرئيسي

الوحدة 5 — pandas: السلاسل وإطار البيانات والفهرسة

pandas هي الأداة التي يقضي فيها ممارس البيانات معظم يومه. مفهومياً الأمر بسيط: إطار البيانات (DataFrame) مصفوفة NumPy ثنائية الأبعاد تحمل صفوفها وأعمدتها تسميات. كلّ القوّة — والفخاخ القليلة — تنبع من هذه الفكرة.

Series وDataFrame: الكائنان

السلسلة (Series) عمود واحد: قيم NumPy زائد فهرس من التسميات. وإطار البيانات مجموعة سلاسل تتقاسم الفهرس نفسه.

import pandas as pd

df = pd.read_csv("orders.csv", parse_dates=["date"])

df.shape # (12480, 6) — صفوف، أعمدة
df.dtypes # نوع كلّ عمود — اقرأه بانتظام
df["amount"] # عمود واحد ← Series
df[["client", "amount"]] # عدّة أعمدة ← DataFrame

أول ما يُفعل أمام أيّ ملفّ مجهول يتلخّص في أربعة أوامر:

df.head()       # الصفوف الخمسة الأولى — كيف تبدو البيانات؟
df.info() # الأنواع وغير الفارغ والذاكرة — هل الأعمدة منمّطة صحيحاً؟
df.describe() # إحصاءات الأعمدة الرقمية — رتب المقادير والقيم القصوى
df["country"].value_counts() # توزيع عمود فئوي — القيم والأخطاء الإملائية

تكشف هذه الأوامر الأربعة جلّ المشكلات قبل أن تصير أخطاء: عمود المبالغ المقروء نصّاً (بسبب «N/A» أو فاصلة عشرية)، والتاريخ الباقي سلسلة نصّية، والفئة المكتوبة بثلاث صيغ.

loc وiloc: انتقاء بلا لبس

تقدّم pandas وصولين صريحين، والانضباط في استخدامهما يجنّب معظم الالتباس:

df.loc[42, "amount"]            # بالتسميات: تسمية الفهرس 42، عمود "amount"
df.iloc[0, 3] # بالمواضع: الصفّ الأول، العمود الرابع

df.loc[df["country"] == "المغرب", ["client", "amount"]] # ترشيح + أعمدة
df.iloc[:100] # أول 100 صفّ

يصبح الفرق حاسماً ما إن يكفّ الفهرس عن كونه 0، 1، 2…: بعد ترتيب أو ترشيح، loc[5] يعني التسمية 5 (وقد تكون في أيّ مكان)، وiloc[5] الصفّ السادس. قاعدة بسيطة: loc افتراضياً، وiloc حين تفكّر بالمواضع.

الترشيح: الأقنعة المنطقية، كما في NumPy

آلية الوحدة 4 تنطبق كما هي، مع التسميات:

large = df[df["amount"] > 1000]

target = df[(df["amount"] > 1000) & (df["country"] == "كندا")] # الأقواس إلزامية

recent = df[df["date"] >= "2026-01-01"] # مقارنات تواريخ مباشرة
gulf = df[df["country"].isin(["السعودية", "الإمارات", "قطر"])]
no_email = df[df["email"].isna()]

isin تستبدل سلاسل |؛ وisna()/notna() تختبران النواقص. والنسبة تُقرأ مباشرة: (df["amount"] > 1000).mean().

إنشاء الأعمدة وتحويلها

df["amount_incl_tax"] = df["amount"] * 1.15                  # موجَّه
df["year"] = df["date"].dt.year # مِلحق التواريخ
df["domain"] = df["email"].str.split("@").str[1] # مِلحق السلاسل
df["segment"] = np.where(df["amount"] > 1000, "مميّز", "عادي")

المِلحقان .dt (التواريخ) و.str (السلاسل) يوجّهان عمليات كانت ستستلزم حلقة. apply بدالّة على كلّ صفّ موجودة، لكنها الملاذ الأخير: أبطأ مئة مرّة من العمليات الموجَّهة، ولا تُبرَّر إلا لمنطق غير قابل فعلاً للاختزال.

تحذير SettingWithCopyWarning

تعديل نتيجة ترشيح (sub_df = df[mask] ثم sub_df["x"] = …) يطلق أشهر تحذيرات pandas: لا تضمن pandas هل تعدّل نسخة أم الجدول الأصلي. الحركتان اللتان تجنّبانه: .copy() صريحة حين تريد جزءاً مستقلاً، و**df.loc[mask, "x"] = value** حين تريد تعديل الأصل. إنها النتيجة المباشرة للعروض/المراجع في الوحدتين 2 و4.

الترتيب وإعادة التسمية وإعادة الفهرسة

df.sort_values("amount", ascending=False)          # ترتيب بسيط
df.sort_values(["country", "amount"], ascending=[True, False]) # ترتيب متعدّد
df.rename(columns={"amt": "amount"}) # إعادة تسمية مقروءة
df.reset_index(drop=True) # فهرس يعود 0..n-1 بعد ترشيح/ترتيب

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

top_clients = (
df[df["date"] >= "2026-01-01"]
.groupby("client")["amount"].sum()
.sort_values(ascending=False)
.head(20)
)

هذه السلسلة — ترشيح، تجميع، ترتيب، رأس — هي الجملة النمطية لتحليل pandas؛ وgroupby الذي يحرّكها موضوع الوحدة 7.

الخلاصة

  • إطار البيانات = مصفوفة NumPy + تسميات صفوف (فهرس) وأعمدة؛ والسلسلة = عمود واحد.
  • على كلّ ملفّ جديد: head وinfo وdescribe وvalue_counts — أربعة أوامر تكشف الأنواع الخاطئة والنواقص والفئات الملوّثة.
  • loc بالتسميات وiloc بالمواضع؛ أقنعة منطقية بأقواس، وisin وisna.
  • أعمدة جديدة بعمليات موجَّهة ومِلحقي .dt و.str؛ وapply ملاذاً أخيراً.
  • .copy() أو df.loc[mask, col] = … ضدّ SettingWithCopyWarning؛ تحويلات مسلسلة قابلة للفحص خطوة خطوة.

الوحدة التالية: التنظيف المنهجي — القيم الناقصة والتكرارات والأنواع — الخطوة التي تقرّر موثوقية كلّ ما بعدها.