# מערך שיעור: ניקוי נתונים📋 מערך מרצה

משך: 2 שעות אקדמיות (90 דקות).

מטרת השיעור: הסטודנטים ילמדו לזהות ולטפל בנתונים חסרים/לא-עקביים לפני ניתוח.

בסוף השיעור הסטודנטים צריכים: לבדוק ערכים חסרים עם isna, לבחור בין fillna ל-dropna לפי הקשר עסקי, ולהמיר עמודת תאריך עם to_datetime.

דגש קריטי: הדגישו ש-fillna/dropna הן החלטות עסקיות, לא רק טכניות — אין "תשובה נכונה" אוטומטית, תלוי בהקשר.

---

## מהלך השיעור

| חלק בשיעור | משך | הערות ודגשים |
| --- | --- | --- |
| פתיחה וחיבור | 5 דקות | הראו DataFrame "מלוכלך" אמיתי — NaN, שמות לא-עקביים |
| isna + הבנת ההיקף | 15 דקות | isna().sum() תמיד ראשון |
| fillna מול dropna | 25 דקות | דיון: מתי כל אחד מתאים, לא רק תחביר |
| rename | 10 דקות | לפני merge |
| to_datetime | 20 דקות | הבעיה: מיון טקסט לא-כרונולוגי, הפתרון |
| תרגול מודרך | 15 דקות | תרגיל 1+2 |

---

## דגשים להעברת השיעור

- fillna מול dropna דורש דיון פתוח, לא רק תחביר — תנו לסטודנטים תרחישים שונים (5% מהשורות חסר משהו לא-קריטי; 60% מהשורות חסר שדה קריטי) ותנו להם להחליט מה מתאים לכל אחד.
- הבעיה של מיון תאריך-כטקסט היא הוכחה חיה חשובה — הראו בפועל "2026-1-5" מגיע לפני "2026-12-1" במיון טקסטואלי, למרות שזה שגוי כרונולוגית.
- קשרו את "בעיית ה-NaN" בקצרה חזרה ל-Nullable Types מיחידת C# היסודות — אותה בעיה בדיוק ("איך מייצגים אין-ערך"), פתרון שונה בכל שפה.

---

## מושגים

**`NaN`** — ערך חסר ב-Pandas.
**`fillna`/`dropna`** — מילוי ערך/הסרת שורה עם חוסר.
**`rename`** — אחוד שמות עמודות.
**`to_datetime`** — המרה לטיפוס תאריך אמיתי.

---

## תרגיל חשיבה

**שאלת פתיחה:** "יש לכם DataFrame של 1000 הזמנות. ב-3 מהן חסר שם לקוח; ב-600 מהן חסר קוד קופון (כי רוב הזמנות לא השתמשו בקופון בכלל). האם תשתמשו ב-dropna על שניהם באותה צורה?"

**מהלך:** הובילו לתובנה: לא! 3 שורות עם שם לקוח חסר כנראה שגיאת נתונים אמיתית — אולי `dropna(subset=["CustomerName"])` הגיוני. אבל 600 מתוך 1000 עם קופון חסר זו כנראה **התנהגות תקינה** ("לא השתמש בקופון") — כאן `fillna("ללא קופון")` הגיוני בהרבה מ-`dropna` שהיה מוחק 60% מהנתונים.

**מה המרצה מראה בסוף:** הריצו `isna().sum()` על DataFrame לדוגמה עם שני סוגי החוסר האלה בדיוק, והראו את המספרים בפועל — 3 מול 600 — כדי לבסס למה הטיפול צריך להיות שונה לכל עמודה, לא מדיניות אחידה על כל ה-DataFrame.
