מה זה?

יש לכם orders.csv ו-customers.csv נפרדים — איך רואים כל הזמנה עם שם הלקוח? merge פותר את זה (בדיוק כמו $lookup ב-MongoDB, או JOIN ב-SQL). ו"כמה הזמנות לכל לקוח, וסכום כולל?" — groupby+agg פותרים את זה (בדיוק כמו GroupBy+Count/Sum ב-LINQ, או $group ב-MongoDB). זהו הרעיון החוזר של הקורס כולו — כל טכנולוגיה עם התחביר שלה, אותה בעיה בדיוק.

מילות מפתח שחשוב לזכור

• merge() — משלב שני DataFrames לפי עמודת מפתח משותפת — ה-JOIN של Pandas

• groupby() — מקבץ שורות לפי ערך עמודה, כהכנה לחישוב מצטבר על כל קבוצה

• agg() — מבצע חישוב מצטבר (סכום, ממוצע, ספירה) על קבוצות מ-groupby

• apply() — מריץ פונקציה מותאמת אישית על כל שורה/עמודה, כשאין פונקציה מובנית מתאימה

# merge — JOIN between two DataFrames
orders = pd.read_csv("orders.csv")      # OrderId, CustomerId, Amount
customers = pd.read_csv("customers.csv") # CustomerId, Name

merged = orders.merge(customers, on="CustomerId")   # combine by shared key
# now every order also has the customer's Name
# groupby + agg — grouping and aggregate computation
summary = orders.groupby("CustomerId").agg(
    TotalOrders=("OrderId", "count"),
    TotalSpent=("Amount", "sum")
).reset_index()
# for each customer: how many orders, and total amount spent — just like GroupBy+Count/Sum in LINQ
# apply — a custom function applied to every row
def categorize(amount):
    if amount > 1000:
        return "VIP"
    elif amount > 100:
        return "Regular"
    return "Small"

orders["Category"] = orders["Amount"].apply(categorize)
# a new column, computed with custom logic

הסבר עיקרי

merge דורש עמודת מפתח משותפת — on="CustomerId" אומר ל-Pandas “שלב שורות שבהן CustomerId זהה בשני ה-DataFrames” — בדיוק כמו FK ב-SQL, או localField/foreignField ב-$lookup של MongoDB. בלי עמודת מפתח תואמת, אין דרך לדעת אילו שורות “שייכות” יחד.

groupby לבד לא עושה כלום — צריך agg — df.groupby("CustomerId") בעצמו רק “מכין” את הקיבוץ (Object ביניים), לא מחשב עדיין שום דבר. agg(...) הוא מה שבפועל מבצע את החישוב על כל קבוצה — סכום, ממוצע, ספירה, או כמה חישובים בו-זמנית עם שמות ברורים (TotalOrders=(...), TotalSpent=(...)).

apply הוא “מוצא אחרון” — כשיש פונקציה מובנית ל-Pandas (כמו .sum(), .mean()), היא כמעט תמיד מהירה יותר מ-apply עם פונקציה מותאמת-אישית, כי Pandas ממטב פעולות מובנות ברמה נמוכה. apply שימושי כשהלוגיקה מורכבת מכדי לבטא עם פעולות מובנות (כמו הקטגוריזציה בדוגמה) — אבל לא ברירת המחדל לכל דבר.

יתרונות

merge משלב מקורות נתונים נפרדים בשורה אחת, בדיוק כמו JOIN ב-SQL; groupby+agg נותנים סטטיסטיקה לפי קבוצה בלי לולאות ידניות; apply נותן גמישות מלאה ללוגיקה מותאמת-אישית כשצריך.

חסרונות

merge עם עמודות מפתח לא-תואמות (טיפוסים שונים, ערכים חסרים) יוצר שורות “יתומות” או ריקות בשקט; apply איטי משמעותית מפעולות Pandas מובנות על DataFrames גדולים — לא לבחור אותו כברירת מחדל.

נקודות חשובות

• merge(on=...) הוא ה-JOIN של Pandas, מקביל ל-$lookup/SQL JOIN

• groupby לבד לא מחשב כלום — צריך agg אחריו לביצוע החישוב בפועל

• apply גמיש אך איטי יותר מפעולות מובנות — פתרון אחרון, לא ראשון

• זהו אותו רעיון (JOIN, GroupBy) שכבר נלמד ב-LINQ וב-MongoDB, רק תחביר שלישי

טעויות נפוצות

• לצפות ש-groupby לבד “יעשה משהו” בלי agg/פונקציה מצטברת אחריו

• להשתמש ב-apply לחישובים פשוטים שיש להם פונקציה מובנית מהירה יותר (sum, mean)

• לשכוח שעמודת המפתח ב-merge חייבת טיפוס תואם בשני הצדדים (למשל int מול string) — אחרת לא מתאחדת נכון

סיכום

merge משלב DataFrames לפי עמודת מפתח משותפת — ה-JOIN של Pandas. groupby+agg מקבצים ומחשבים סטטיסטיקה לפי קבוצה — groupby לבדו רק מכין, agg מבצע את החישוב בפועל. apply מריץ לוגיקה מותאמת-אישית על כל שורה, שימושי כשאין פונקציה מובנית מתאימה, אך איטי יותר ולכן לא ברירת מחדל. אלה שלושת הכלים המרכזיים לעיבוד נתונים אמיתי ב-Pandas.

דוקומנטציה רשמית

Pandas — Merge, join, concatenate

Pandas — GroupBy


תרגילים

תרגיל 1 — merge בסיסי

המשימה: צרו שני DataFrames קטנים (orders, products) עם עמודת מפתח משותפת (ProductId), ושלבו אותם עם merge.

בדיקה: התוצאה המשולבת מכילה עמודות משני המקורות, בשורה נכונה לכל הזמנה.

תרגיל 2 — groupby+agg

המשימה: מתוך DataFrame הזמנות, קבצו לפי ProductId וחשבו סכום כמות (sum) וממוצע מחיר (mean) לכל מוצר.

בדיקה: כל מוצר מוצג עם סכום וממוצע נכונים, לא שורה בודדת ריקה.


פרויקט מסכם

המשימה: בנו דוח “ביצועי מוצרים” משילוב merge+groupby+agg+apply.

דרישות:

  1. merge בין orders ל-products לפי ProductId
  2. groupby("ProductName") עם agg — סכום כמות שנמכרה וסך הכנסה
  3. apply שמוסיף עמודת Tier (“רב-מכר” אם סך הכנסה מעל סף מסוים, אחרת “רגיל”)

בדיקה: הדוח הסופי מציג לכל מוצר את שמו, סטטיסטיקת המכירות, וה-Tier הנכון לפי הסף שהוגדר.

מה בפרק הבא

בפרק הבא — ניקוי נתונים: fillna, dropna, rename, to_datetime — איך מטפלים בנתונים חסרים ולא-אחידים לפני שהם “מזהמים” ניתוח.