ברוכים הבאים ליחידת הלימוד "ניהול ועיבוד נתונים עם Pandas" בקורס "תכנות וניתוח נתונים בשפת פייתון" (20606). ספריית Pandas היא כלי עבודה חיוני בעולם מדעי הנתונים, המאפשרת טיפול יעיל ונוח בנתונים טבלאיים. יחידה זו תסקור את המושגים המרכזיים, מבני הנתונים והפעולות הנפוצות ביותר ב-Pandas, תוך התמקדות בהיבטים הרלוונטיים לבחינות הקורס וליישומים מעשיים.
מבוא ל-Pandas: למה וכיצד?
Pandas היא ספריית קוד פתוח בפייתון המספקת מבני נתונים קלים לשימוש וכלים לניתוח נתונים. היא נבנתה על גבי ספריית NumPy ומצטיינת בטיפול בנתונים טבלאיים, המהווים את הבסיס למרבית עבודות ניתוח הנתונים.
מבני הנתונים המרכזיים: Series ו-DataFrame
Pandas מציעה שני מבני נתונים עיקריים שכל סטודנט חייב להכיר היטב:
Series
מבנה נתונים חד-ממדי (טור בודד) המכיל רצף של ערכים (מכל סוג נתונים) ואינדקס משויך לכל ערך. ניתן לחשוב עליו כעל עמודה בטבלה או רשימה עם תוויות.
DataFrame
מבנה נתונים דו-ממדי (טבלה) המכיל אוסף של עמודות, כאשר כל עמודה היא אובייקט Series. ל-DataFrame יש אינדקס לשורות ואינדקס לעמודות. זהו מבנה הנתונים הנפוץ ביותר לטיפול בנתונים טבלאיים.
יצירה וגישה לנתונים
ניתן ליצור Series מליסטה, מערך NumPy או מילון. DataFrame ניתן ליצור ממילון של Series/ליסטות, מליסטה של מילונים, או מקובץ חיצוני (CSV, Excel). גישה לנתונים מתבצעת באמצעות אינדקסים, תוויות או תנאים בוליאניים.
- גישה לפי תווית (label-based): שימוש ב-
.loc[]. לדוגמה,df.loc[row_label, col_label]. - גישה לפי מיקום (integer-location based): שימוש ב-
.iloc[]. לדוגמה,df.iloc[row_index, col_index]. - גישה ישירה:
df['column_name']לגישה לעמודה, אוdf[boolean_condition]לסינון שורות.
.loc משמש לגישה לפי תוויות (שמות שורות/עמודות), .iloc משמש לגישה לפי מיקום מספרי (אינדקסים של שורות/עמודות), ו-[] משמש לרוב לגישה לעמודה לפי שמה, או לסינון בוליאני של שורות. טעות נפוצה היא לנסות להשתמש ב-.loc עם אינדקסים מספריים כאשר האינדקס אינו מספרי, או להפך. שימו לב במיוחד לטווחים (slices) – .loc כולל את נקודת הסיום, בעוד .iloc אינו כולל אותה (כמו ב-Python רגיל).פעולות עיבוד נתונים חיוניות
סינון ובחירה
סינון נתונים הוא פעולה בסיסית וחיונית. ניתן לסנן שורות לפי תנאים בוליאניים (לדוגמה, df[df['Age'] > 30]) או לבחור עמודות ספציפיות (לדוגמה, df[['Name', 'Age']]).
טיפול בנתונים חסרים
נתונים חסרים (NaN - Not a Number) הם תופעה נפוצה. Pandas מספקת כלים לזיהוי, מחיקה או מילוי שלהם:
.isnull()/.isna(): מחזיר DataFrame בוליאני המציין היכן יש ערכים חסרים..notnull()/.notna(): ההפך מ-isnull()..dropna(): מוחק שורות או עמודות המכילות ערכים חסרים..fillna(value): ממלא ערכים חסרים בערך ספציפי (לדוגמה, 0, ממוצע, חציון).
מיון וסידור
מיון נתונים מאפשר להציג אותם בסדר מסוים:
.sort_values(by='column_name', ascending=True/False): ממיין לפי ערכים בעמודה ספציפית..sort_index(ascending=True/False): ממיין לפי אינדקס השורות.
איחוד, קיבוץ ושינוי צורה
קיבוץ נתונים (groupby)
פעולת .groupby() מאפשרת לקבץ שורות על בסיס ערכים זהים בעמודה אחת או יותר, ולאחר מכן לבצע פעולות אגרגציה (כמו סכימה, ממוצע, ספירה) על כל קבוצה בנפרד. זוהי אחת הפעולות החזקות ביותר ב-Pandas לניתוח נתונים.
איחוד נתונים (merge/join)
לעיתים קרובות, הנתונים שאנו מנתחים מפוזרים במספר טבלאות. Pandas מאפשרת לאחד אותן:
.merge()
פונקציה גמישה לאיחוד שני DataFrames על בסיס עמודות משותפות (מפתחות). מאפשרת סוגי איחוד שונים (inner, outer, left, right) וציון מפורש של עמודות האיחוד.
.join()
שיטה המשמשת לאיחוד DataFrames על בסיס האינדקסים שלהם, או על בסיס אינדקס של DataFrame אחד ועמודה של השני. שימושית כאשר האינדקסים הם המפתחות לאיחוד.
שאלות לדיון
- הסבר מתי תבחר להשתמש ב-
.loc[]ומתי ב-.iloc[]בעת גישה לנתונים ב-DataFrame. תן דוגמה לכל מקרה. - יש לך DataFrame עם עמודה 'Sales' המכילה ערכים חסרים. תאר שתי גישות שונות לטיפול בערכים החסרים הללו, והסבר מתי תעדיף כל אחת מהן.
- כיצד תשתמש בפעולת
.groupby()כדי לחשב את הממוצע של עמודה 'Price' עבור כל קטגוריה ב-DataFrame המכיל עמודות 'Category' ו-'Price'? - מה ההבדל העיקרי בין
pd.merge()לביןdf.join(), ומתי תבחר להשתמש בכל אחת מהן?
נקודות לתשובת מודל
.loc[]vs.iloc[]:.loc[]לגישה לפי תוויות (שמות עמודות, אינדקסים מותאמים אישית),.iloc[]לגישה לפי מיקום מספרי (אינדקסים 0-based). דוגמאות:df.loc['row_A', 'col_B']ו-df.iloc[0, 1].- טיפול בנתונים חסרים:
- מחיקה (
.dropna()): מתאים כאשר כמות הנתונים החסרים קטנה יחסית ואינה פוגעת משמעותית בגודל המדגם, או כאשר אין דרך סבירה למלא אותם. - מילוי (
.fillna()): מתאים כאשר רוצים לשמר את השורות. ניתן למלא ב-0, בממוצע/חציון העמודה (לנתונים מספריים), או בערך קודם/עוקב (method='ffill'/'bfill'). הבחירה תלויה בהקשר הנתונים ובהשפעה על הניתוח.
- מחיקה (
- שימוש ב-
.groupby():df.groupby('Category')['Price'].mean(). הסבר: קיבוץ לפי 'Category', בחירת עמודת 'Price', וחישוב ממוצע לכל קבוצה. pd.merge()vsdf.join():pd.merge(): גמיש יותר, מאפשר איחוד על בסיס עמודות ספציפיות (מפתחות) בשני ה-DataFrames, עם שליטה מלאה על סוג האיחוד (inner, outer, left, right).df.join(): מיועד בעיקר לאיחוד על בסיס האינדקסים של ה-DataFrames. ניתן גם לאחד אינדקס של אחד עם עמודה של השני. פשוט יותר לשימוש במקרים אלה.