طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 244 · علم البيانات للويب
الدرس 13 · الوحدة 7: جمع البيانات من مصادر متعددة

الدمج merge والربط بين الجداول

بيانات موزّعة على جداول؛ كيف نربطها في جدولٍ واحد دون فقدٍ أو تكرار؟ ⏱ نحو 45 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تربط الجداول بعمودٍ مشترك بـ merge.
  • تختار نوع الدمج المناسب بـ how.
  • تدمج عند اختلاف أسماء المفاتيح.
  • تتحقّق من سلامة الدمج بعدد الصفوف.

١البيانات موزّعة على جداول

نادرًا ما تجد كل ما تحتاجه في جدولٍ واحد: الزيارات في جدول، وبيانات المستخدمين في آخر، والطلبات في ثالث. الدمج merge يربطها عبر عمودٍ مشترك (المفتاح)، تمامًا كـ JOIN في SQL الذي عرفته.

main.py
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)
Shell×
>>> %Run main.py
user_id visits country
0 1 12 SA
1 2 5 EG
2 3 8 SA
>>>

النتيجة صفٌّ لكل تطابق في المفتاح user_id. لاحظ أن المستخدم 4 (بلا بلد) والمستخدم 5 (بلا زيارات) سقطا — هذا الدمج الداخلي.

٢أنواع الدمج: how

ماذا نفعل بالصفوف غير المتطابقة؟ يحدّدها how:

howيُبقيالاستعمال
inner (افتراضي)المتطابق في الجدوليننريد المكتمل فقط
leftكل صفوف اليسارنحتفظ بكل الزيارات ولو بلا بلد
outerكل الصفوف من الجهتينلا نفقد شيئًا
main.py
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()))
Shell×
>>> %Run main.py
user_id visits country
0 1 12 SA
1 2 5 EG
2 3 8 SA
3 4 3 NaN
قيم مفقودة في country: 1
>>>

٣حين تختلف أسماء المفاتيح

إن اختلف اسم المفتاح بين الجدولين، نحدّده لكلٍّ بـ left_on وright_on:

main.py
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"]])
Shell×
>>> %Run main.py
name total
0 سارة 300
1 خالد 150
2 نورة 90
>>>

توقّع وتحقّق

لربط جدولين عبر عمود مشترك:

للاحتفاظ بكل صفوف اليسار:

الدمج الداخلي inner يُبقي:

عند اختلاف اسمي المفتاح نستخدم:

الخلاصة

تحدٍّ برمجي: اربط واحسب

متقدم

ادمج الزيارات ببيانات المستخدمين (inner)، ثم اطبع عدد الصفوف الناتجة، وإجمالي زيارات دولة SA.

المطلوب:
  • ادمج على user_id.
  • اطبع عدد الصفوف، ثم مجموع visits حيث country == "SA".

ابدأ من هذا الكود، واضغط ▶ شغّل هنا لتكتب حلّك وتجرّبه مباشرة:

main.py
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
المطلوب×
3
20
💡 تلميح 1
m = visits.merge(users, on="user_id").
💡 تلميح 2
رشّح ثم اجمع: m[m["country"]=="SA"]["visits"].sum().

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

main.py
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()))
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس