ניקוי נתונים — fillna, dropna, rename, to_datetime
מה זה?
נתונים אמיתיים (לא הדוגמאות הנקיות ששימשו עד עכשיו) כמעט תמיד “מלוכלכים” — ערכים חסרים (NaN), עמודות עם שמות לא-עקביים ("cust_name" לעומת "CustomerName"), תאריכים שנשמרו כטקסט חופשי. עיבוד/ניתוח על נתונים כאלה בלי ניקוי קודם מייצר תוצאות שגויות בשקט — בדיוק כמו ה--1 המסוכן ל"ערך ריק" ב-C# (מיחידת ה-Nullable). ניקוי נתונים הוא תמיד השלב שקודם לכל ניתוח אמיתי.
מילות מפתח שחשוב לזכור
• NaN (Not a Number) — הייצוג של Pandas ל"ערך חסר", מקביל ל-null/None
• fillna() — ממלא ערכים חסרים בערך ברירת מחדל (0, ממוצע, מחרוזת קבועה)
• dropna() — מסיר שורות (או עמודות) עם ערכים חסרים לחלוטין
• rename() — משנה שמות עמודות לעקביים
• to_datetime() — ממיר עמודת טקסט/מספר לטיפוס תאריך אמיתי, מאפשר פעולות תאריך (מיון כרונולוגי, חישוב הפרשים)
# NaN — actual missing values
df.isna().sum() # how many missing values are in each column — always check this first
# fillna — filling with a default value
df["Score"] = df["Score"].fillna(0) # a fixed value
df["Age"] = df["Age"].fillna(df["Age"].mean()) # the column's mean — more common in practice# dropna — removing rows with missing values
df_clean = df.dropna() # removes a row if **every** column in it is missing something
df_clean = df.dropna(subset=["Email"]) # removes only if Email specifically is missing# rename — consistent column names
df = df.rename(columns={"cust_name": "CustomerName", "amt": "Amount"})
# to_datetime — converting to a real date type
df["OrderDate"] = pd.to_datetime(df["OrderDate"]) # from "2026-01-15" (text) to a date type
df_sorted = df.sort_values("OrderDate") # now a real chronological sort, not by textהסבר עיקרי
fillna מול dropna — בחירה עסקית, לא רק טכנית — dropna מוחק מידע (השורה כולה נעלמת), מתאים כשמעט שורות מושפעות ואי אפשר “לנחש” ערך הגיוני. fillna שומר את השורה ומחליף רק את הערך החסר — מתאים כשיש דרך הגיונית להשלים (ממוצע, 0, “לא ידוע”) בלי לאבד מידע אחר בשורה. הבחירה תלויה בהקשר העסקי, לא בכלל אוטומטי.
to_datetime הוא לא “עוד המרת טיפוס” — בלי המרה, עמודת תאריכים שמורה כטקסט ממוינת לקסיקוגרפית (“2026-1-5” לפני “2026-12-1” למרות שכרונולוגית זה הפוך) — בעיה שקטה ומסוכנת. אחרי to_datetime, sort_values על אותה עמודה ממיין באמת כרונולוגית, ואפשר גם לחשב הפרשי זמן (df["Date"].max() - df["Date"].min()).
למה rename חשוב לפני שילוב מקורות — כשמאחדים כמה DataFrames ממקורות שונים (כמו בפרויקט ה-ETL הקרוב), כל אחד לרוב מגיע עם מוסכמת שמות שונה. rename מאחד אותם לשמות עקביים לפני merge/groupby — אחרת merge(on="CustomerId") פשוט נכשל בשקט אם עמודה אחת נקראת customer_id.
יתרונות
fillna/dropna נותנים שליטה מפורשת בטיפול בנתונים חסרים, במקום שהם “יזהמו” חישובים בשקט; to_datetime מאפשר מיון וחישובי תאריך נכונים; rename מבטיח עקביות לפני שילוב מקורות.
חסרונות
fillna עם ערך שגוי (למשל 0 כשזה לא הגיוני עסקית) עלול לעוות תוצאות בדיוק כמו הבעיה שניסה לפתור; dropna שמסיר יותר מדי שורות עלול לאבד מידע רב אם לא נבדק היקף ההשפעה קודם (isna().sum()).
נקודות חשובות
• NaN = “ערך חסר” ב-Pandas, מקביל ל-null ב-C#
• fillna שומר שורה וממלא ערך; dropna מסיר שורה שלמה
• to_datetime הכרחי לפני מיון/חישוב כרונולוגי נכון על עמודת תאריכים
• rename מאחד שמות עמודות עקביים, קריטי לפני merge בין מקורות שונים
טעויות נפוצות
• להשתמש ב-dropna() בלי subset ולאבד שורות בגלל עמודה לא-רלוונטית שחסרה בהן
• לשכוח to_datetime ולמיין תאריכים כטקסט — סדר שגוי בלי שגיאה גלויה
• למלא fillna בערך “שרירותי” (כמו 0) שמעוות ממוצעים וחישובים סטטיסטיים אחרים
סיכום
ניקוי נתונים הוא תמיד השלב שקודם לניתוח אמיתי. NaN מייצג ערכים חסרים; fillna ממלא אותם בערך הגיוני (שומר שורה), dropna מסיר שורות/עמודות עם חוסר (מאבד מידע במודע). rename מאחד שמות עמודות לעקביים, קריטי לפני שילוב מקורות. to_datetime הופך טקסט תאריך לטיפוס תאריך אמיתי, מאפשר מיון כרונולוגי וחישובי הפרשים — בלעדיו, “מיון תאריכים” עלול להיות שגוי בשקט.
דוקומנטציה רשמית
Pandas — Working with missing data
תרגילים
תרגיל 1 — בדיקה וטיפול בערכים חסרים
המשימה: טענו DataFrame עם כמה ערכי NaN מכוונים, ספרו כמה חסרים יש בכל עמודה (isna().sum()), ואז מלאו עמודה מספרית בממוצע ומחקו שורות שחסר בהן שדה קריטי.
בדיקה: לפני הניקוי, isna().sum() מציג ערכים חסרים; אחרי הניקוי, אין NaN בעמודה שמולאה, והשורות עם השדה הקריטי החסר נעלמו.
תרגיל 2 — to_datetime ומיון
המשימה: צרו DataFrame עם עמודת תאריכים כטקסט בפורמט לא-אחיד סטנדרטי, המירו עם to_datetime, ומיינו כרונולוגית.
בדיקה: לפני ההמרה, מיון לפי הטקסט נותן סדר שגוי; אחרי ההמרה, הסדר כרונולוגי נכון.
פרויקט מסכם
המשימה: נקו DataFrame “מלוכלך” של הזמנות ממקור חיצוני מדומה.
דרישות:
- עמודות עם שמות לא-עקביים (
cust_id,amt,dt) — אחדו עםrenameלשמות ברורים - עמודת סכום עם כמה ערכים חסרים — מלאו עם הממוצע (
fillna) - עמודת תאריך כטקסט — המירו עם
to_datetimeומיינו כרונולוגית - שורות עם
CustomerIdחסר לגמרי (שדה קריטי) — הסירו עםdropna(subset=...)
בדיקה: ה-DataFrame הסופי נקי — בלי ערכים חסרים בשדות קריטיים, שמות עמודות עקביים, וממוין כרונולוגית נכון.
מה בפרק הבא
בפרק הבא — Extract + Load: איך שולפים נתונים ממקורות אמיתיים (API עם requests) וכותבים תוצאות בחזרה למסד נתונים (to_sql) — הצעדים הראשון והאחרון של כל צנרת ETL.