الدمج merge والربط بين الجداول
بيانات موزّعة على جداول؛ كيف نربطها في جدولٍ واحد دون فقدٍ أو تكرار؟ ⏱ نحو 45 دقيقة.
- تربط الجداول بعمودٍ مشترك بـ
merge. - تختار نوع الدمج المناسب بـ
how. - تدمج عند اختلاف أسماء المفاتيح.
- تتحقّق من سلامة الدمج بعدد الصفوف.
١البيانات موزّعة على جداول
نادرًا ما تجد كل ما تحتاجه في جدولٍ واحد: الزيارات في جدول، وبيانات المستخدمين في آخر، والطلبات في ثالث. الدمج merge يربطها عبر عمودٍ مشترك (المفتاح)، تمامًا كـ JOIN في SQL الذي عرفته.
import pandas as pdvisits = pd.DataFrame({ "user_id": [1, 2, 3, 4], "visits": [12, 5, 8, 3],})users = pd.DataFrame({ "user_id": [1, 2, 3, 5], "country": ["SA", "EG", "SA", "AE"],})# ربط الزيارات ببلد المستخدم عبر user_idmerged = visits.merge(users, on="user_id")print(merged)
النتيجة صفٌّ لكل تطابق في المفتاح user_id. لاحظ أن المستخدم 4 (بلا بلد) والمستخدم 5 (بلا زيارات) سقطا — هذا الدمج الداخلي.
٢أنواع الدمج: how
ماذا نفعل بالصفوف غير المتطابقة؟ يحدّدها how:
| how | يُبقي | الاستعمال |
|---|---|---|
| inner (افتراضي) | المتطابق في الجدولين | نريد المكتمل فقط |
| left | كل صفوف اليسار | نحتفظ بكل الزيارات ولو بلا بلد |
| outer | كل الصفوف من الجهتين | لا نفقد شيئًا |
import pandas as pdvisits = pd.DataFrame({ "user_id": [1, 2, 3, 4], "visits": [12, 5, 8, 3],})users = pd.DataFrame({ "user_id": [1, 2, 3, 5], "country": ["SA", "EG", "SA", "AE"],})# left: نبقي كل الزيارات، والبلد فارغ إن لم يوجدleft = visits.merge(users, on="user_id", how="left")print(left)print("قيم مفقودة في country:", int(left["country"].isna().sum()))
٣حين تختلف أسماء المفاتيح
إن اختلف اسم المفتاح بين الجدولين، نحدّده لكلٍّ بـ left_on وright_on:
import pandas as pdorders = pd.DataFrame({"uid": [1, 2, 3], "total": [300, 150, 90]})users = pd.DataFrame({"user_id": [1, 2, 3], "name": ["سارة", "خالد", "نورة"]}) m = orders.merge(users, left_on="uid", right_on="user_id")print(m[["name", "total"]])
توقّع وتحقّق
لربط جدولين عبر عمود مشترك:
للاحتفاظ بكل صفوف اليسار:
الدمج الداخلي inner يُبقي:
عند اختلاف اسمي المفتاح نستخدم:
الخلاصة
mergeيربط الجداول عبر مفتاحٍ مشترك، كـJOINفيSQL.howيحدّد مصير غير المتطابق:innerالمكتمل،leftكل اليسار،outerالجميع.- عند اختلاف الأسماء نستخدم
left_onوright_on. - تحقّق من عدد الصفوف بعد الدمج؛ الدمج مصدرٌ شائع لأخطاء صامتة.
تحدٍّ برمجي: اربط واحسب
متقدمادمج الزيارات ببيانات المستخدمين (inner)، ثم اطبع عدد الصفوف الناتجة، وإجمالي زيارات دولة SA.
- ادمج على
user_id. - اطبع عدد الصفوف، ثم مجموع
visitsحيثcountry == "SA".
ابدأ من هذا الكود، واضغط ▶ شغّل هنا لتكتب حلّك وتجرّبه مباشرة:
import pandas as pdvisits = pd.DataFrame({ "user_id": [1, 2, 3, 4], "visits": [12, 5, 8, 3],})users = pd.DataFrame({ "user_id": [1, 2, 3, 5], "country": ["SA", "EG", "SA", "AE"],})# ادمج ثم اطبع عدد الصفوف ومجموع زيارات SA
💡 تلميح 1
m = visits.merge(users, on="user_id").💡 تلميح 2
m[m["country"]=="SA"]["visits"].sum().حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.
import pandas as pdvisits = pd.DataFrame({ "user_id": [1, 2, 3, 4], "visits": [12, 5, 8, 3],})users = pd.DataFrame({ "user_id": [1, 2, 3, 5], "country": ["SA", "EG", "SA", "AE"],})m = visits.merge(users, on="user_id")print(len(m))print(int(m[m["country"] == "SA"]["visits"].sum()))