الوحدة 7 — الدمج والتجميع والجداول المحورية
تصل البيانات الحقيقية قطعاً: الطلبات في جدول، والعملاء في آخر، والمنتجات في ثالث. والأسئلة التي تهمّ أهل المهنة مجاميع: الإيراد لكلّ شريحة، ومتوسّط السلّة لكلّ شهر. تغطّي هذه الوحدة الآليتين اللتين تصلان القطع بالإجابات — وفخاخهما التي تنتج أرقاماً خاطئة دون رفع أيّ خطأ.
merge: دمج جدولين
enriched_orders = orders.merge(
clients,
on="client_id", # مفتاح الدمج
how="left", # نوع الدمج
)
الأنواع الأربعة ومتى تُستعمل:
how= | ما يُحتفَظ به | الاستعمال النمطي |
|---|---|---|
inner | المفاتيح الحاضرة في الجانبين | تقاطع مصدرين موثوقين |
left | كامل الجدول الأيسر | إثراء بلا فقدان صفوف — الافتراضي العاقل |
right | كامل الجدول الأيمن | نادر — أعد كتابته left معكوساً |
outer | كلّ شيء من الجانبين | تدقيقات مطابقة المصادر |
مع how="left"، تتلقّى الطلبات بلا عميل مطابق NaN في أعمدة العملاء — مرئي وقابل للتتبّع. أمّا مع inner فتختفي: inner غير المدروس هو أهدأ طريقة لفقدان 8% من الإيراد في تحليل.
عُدّ قبل وبعد. يجب أن يعيد left عدد صفوف الجدول الأيسر بالضبط؛ فإن أعاد أكثر فمفتاح اليمين فيه تكرارات وكلّ صفّ أيسر تضاعف — وستنتفخ المجاميع اللاحقة في صمت. وعُدّ غير المتطابق: result["عمود_من_اليمين"].isna().sum(). هذه الأسطر الأربعة من الضبط تمنع أغلى حادثي دمج.
assert len(result) == len(orders), "تضاعف صفوف: مفتاح يمين غير فريد"
print(f"بلا مطابقة: {result['segment'].isna().mean():.1%}")
حين يختلف اسما المفتاحين: left_on="client_id", right_on="id". وحين تتعايش أعمدة متجانسة الاسم: suffixes=("", "_client").
groupby: قسّم، طبّق، اجمع
النمط المفاهيمي: قسّم الجدول إلى فئات، طبّق تجميعاً على كلّ فئة، اجمع النتائج.
df.groupby("segment")["amount"].sum() # تجميع واحد
df.groupby("segment")["amount"].agg(["count", "mean", "sum"]) # عدّة تجميعات
# عدّة مفاتيح وتجميعات مسمّاة — الصيغة الأكثر مقروئية
recap = df.groupby(["segment", "country"]).agg(
order_count=("order_id", "count"),
revenue=("amount", "sum"),
avg_basket=("amount", "mean"),
).reset_index()
reset_index() في النهاية تحوّل الناتج المفهرس جدولاً مسطّحاً — وهو ما تريده لاحقاً في الغالب (دمج، تصدير، رسم).
ويستحقّ التجميع الزمني ذكره: مع pd.Grouper أو resample ينتج السلاسل الشهرية التي تملأ كلّ التقارير:
monthly_revenue = df.set_index("date")["amount"].resample("ME").sum()