שליטה בעיצוב נתונים מחדש עם טבלאות ציר בפייתון Pandas. צלילה עמוקה לתחביר, טכניקות מתקדמות ודוגמאות מעשיות לניתוח נתונים גלובלי.
טבלאות ציר בפייתון Pandas: מדריך מקיף לעיצוב מחדש של נתונים
בעולם ניתוח הנתונים, היכולת לסכם, לצבור ולארגן מחדש נתונים היא לא רק מיומנות - זו מעצמה. נתונים גולמיים, בצורתם המקורית, דומים לעתים קרובות לספר חשבונות מפורט ונרחב. הוא עשיר במידע אך קשה לפרש אותו. כדי לחלץ תובנות משמעותיות, עלינו להפוך את ספר החשבונות הזה לסיכום תמציתי. זה בדיוק המקום שבו טבלאות ציר מצטיינות, ועבור מתכנתי פייתון, ספריית Pandas מספקת כלי רב עוצמה וגמיש: pivot_table().
מדריך זה מיועד לקהל עולמי של אנליסטים, מדענים וחובבי פייתון. אנו נצלול לעומק לתוך המכניקה של טבלאות ציר של Pandas, ונעבור ממושגי יסוד לטכניקות מתקדמות. בין אם אתם מסכמים נתוני מכירות מיבשות שונות, מנתחים נתוני אקלים בין אזורים או עוקבים אחר מדדי פרויקט עבור צוות מבוזר, שליטה בטבלאות ציר תשנה באופן מהותי את הגישה שלכם לחקר נתונים.
מהי בדיוק טבלת ציר?
אם אי פעם השתמשתם בתוכנת גיליונות אלקטרוניים כמו Microsoft Excel או Google Sheets, אתם כנראה מכירים את הרעיון של טבלת ציר. זוהי טבלה אינטראקטיבית המאפשרת לכם לארגן מחדש ולסכם עמודות ושורות נתונים נבחרות ממערך נתונים גדול יותר כדי להשיג דוח רצוי.
טבלת ציר עושה שני דברים עיקריים:
- צבירה: היא מחשבת סטטיסטיקת סיכום (כגון סכום, ממוצע או ספירה) עבור נתונים מספריים המקובצים לפי קטגוריה אחת או יותר.
- עיצוב מחדש: היא הופכת נתונים מפורמט 'ארוך' לפורמט 'רחב'. במקום שכל הערכים יהיו בעמודה אחת, היא 'מצירה' ערכים ייחודיים מעמודה לעמודות חדשות בפלט.
הפונקציה pivot_table() של Pandas מביאה פונקציונליות עוצמתית זו ישירות לתוך זרימת העבודה של ניתוח הנתונים שלכם בפייתון, ומאפשרת עיצוב נתונים הניתן לשחזור, לכתיבת סקריפטים ולשינוי גודל.
הגדרת הסביבה ונתוני הדוגמה שלכם
לפני שנתחיל, ודאו שספריית Pandas מותקנת. אם לא, תוכלו להתקין אותה באמצעות pip, מתקין החבילות של פייתון:
pip install pandas
כעת, בואו נייבא אותה בסקריפט או במחברת הפייתון שלנו:
import pandas as pd
import numpy as np
יצירת מערך נתוני מכירות גלובלי
כדי להפוך את הדוגמאות שלנו למעשיות ורלוונטיות גלובלית, ניצור מערך נתונים סינתטי המייצג נתוני מכירות עבור חברת מסחר אלקטרוני רב-לאומית. מערך נתונים זה יכלול מידע על מכירות מאזורים, מדינות וקטגוריות מוצרים שונות.
# Create a dictionary of data
data = {
'TransactionID': range(1, 21),
'Date': pd.to_datetime([
'2023-01-15', '2023-01-16', '2023-01-17', '2023-02-10', '2023-02-11',
'2023-02-12', '2023-03-05', '2023-03-06', '2023-03-07', '2023-01-20',
'2023-01-21', '2023-02-15', '2023-02-16', '2023-03-10', '2023-03-11',
'2023-01-18', '2023-02-20', '2023-03-22', '2023-01-25', '2023-02-28'
]),
'Region': [
'North America', 'Europe', 'Asia', 'North America', 'Europe', 'Asia', 'North America', 'Europe', 'Asia', 'Europe',
'Asia', 'North America', 'Europe', 'Asia', 'North America', 'Asia', 'Europe', 'North America', 'Europe', 'Asia'
],
'Country': [
'USA', 'Germany', 'Japan', 'Canada', 'France', 'India', 'USA', 'UK', 'China', 'Germany',
'Japan', 'USA', 'France', 'India', 'Canada', 'China', 'UK', 'USA', 'Germany', 'India'
],
'Product_Category': [
'Electronics', 'Apparel', 'Electronics', 'Books', 'Apparel', 'Electronics', 'Books', 'Electronics', 'Apparel',
'Apparel', 'Books', 'Electronics', 'Books', 'Apparel', 'Electronics', 'Books', 'Apparel', 'Books', 'Electronics', 'Electronics'
],
'Units_Sold': [10, 5, 8, 20, 7, 12, 15, 9, 25, 6, 30, 11, 18, 22, 14, 28, 4, 16, 13, 10],
'Unit_Price': [1200, 50, 900, 15, 60, 1100, 18, 950, 45, 55, 12, 1300, 20, 40, 1250, 14, 65, 16, 1150, 1050]
}
# Create DataFrame
df = pd.DataFrame(data)
# Calculate Revenue
df['Revenue'] = df['Units_Sold'] * df['Unit_Price']
# Display the first few rows of the DataFrame
print(df.head())
מערך נתונים זה נותן לנו בסיס מוצק עם שילוב של נתונים קטגוריים (אזור, מדינה, קטגוריית מוצר), נתונים מספריים (יחידות שנמכרו, הכנסות) ונתוני סדרות זמן (תאריך).
האנטומיה של pivot_table()
הפונקציה pivot_table() של Pandas היא רב-תכליתית להפליא. בואו נפרק את הפרמטרים החשובים ביותר שלה:
pandas.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, margins_name='All')
- data: ה- DataFrame שברצונך לציר.
- values: העמודה/ות המכילות את הנתונים שיש לצבור. אם לא מצוין, ייעשה שימוש בכל העמודות המספריות הנותרות.
- index: העמודה/ות שערכיהן הייחודיים יהוו את השורות של טבלת הציר החדשה. זה נקרא לפעמים 'מפתח הקיבוץ'.
- columns: העמודה/ות שערכיהן הייחודיים 'יצורו' ליצירת העמודות של הטבלה החדשה.
- aggfunc: פונקציית הצבירה שיש להחיל על ה'ערכים'. זה יכול להיות מחרוזת כמו 'sum', 'mean', 'count', 'min', 'max', או פונקציה כמו
np.sum. אפשר גם להעביר רשימה של פונקציות או מילון כדי להחיל פונקציות שונות על עמודות שונות. ברירת המחדל היא 'mean'. - fill_value: ערך להחלפת תוצאות חסרות (NaNs) בטבלת הציר.
- margins: בוליאני. אם מוגדר ל-
True, הוא מוסיף סכומי ביניים עבור שורות ועמודות (הידוע גם כסכום כולל). - margins_name: השם עבור השורה/עמודה המכילה את הסכומים כאשר
margins=True. ברירת המחדל היא 'All'.
טבלת הציר הראשונה שלכם: דוגמה פשוטה
בואו נתחיל בשאלה עסקית נפוצה: "מהו סך ההכנסות שנוצרו על ידי כל קטגוריית מוצרים?"
כדי לענות על כך, עלינו:
- השתמשו ב-
Product_Categoryעבור השורות (index). - צברו את העמודה
Revenue(values). - השתמשו בסכום כפונקציית הצבירה שלנו (aggfunc).
# Simple pivot table to see total revenue by product category
category_revenue = pd.pivot_table(df,
values='Revenue',
index='Product_Category',
aggfunc='sum')
print(category_revenue)
פלט:
Revenue
Product_Category
Apparel 1645
Books 1184
Electronics 56850
באופן מיידי, יש לנו סיכום ברור ותמציתי. יומן הרישום הגולמי בן 20 השורות עוצב מחדש לטבלה בת 3 שורות שעונה ישירות על שאלתנו. זהו הכוח הבסיסי של טבלת ציר.
הוספת ממד עמודה
כעת, בואו נרחיב זאת. מה אם נרצה לראות את סך ההכנסות לפי קטגוריית מוצרים, אך גם מחולקות לפי אזור? זה המקום שבו הפרמטר columns נכנס לתמונה.
# Pivot table with index and columns
revenue_by_category_region = pd.pivot_table(df,
values='Revenue',
index='Product_Category',
columns='Region',
aggfunc='sum')
print(revenue_by_category_region)
פלט:
Region Asia Europe North America Product_Category Apparel 1125.0 625.0 NaN Books 336.0 360.0 488.0 Electronics 13200.0 14550.0 29100.0
פלט זה עשיר בהרבה. יצרנו את הערכים הייחודיים מעמודת 'Region' ('Asia', 'Europe', 'North America') לעמודות חדשות. כעת אנו יכולים להשוות בקלות כיצד קטגוריות מוצרים שונות מתפקדות בין אזורים. אנו רואים גם ערך NaN (לא מספר). זה מצביע על כך שלא נרשמו מכירות 'Apparel' עבור 'North America' במערך הנתונים שלנו. זהו מידע בעל ערך בפני עצמו!
טכניקות ציר מתקדמות
היסודות חזקים, אך הגמישות האמיתית של pivot_table() נחשפת בתכונות המתקדמות שלה.
טיפול בערכים חסרים עם fill_value
ה- NaN בטבלה הקודמת שלנו מדויק, אך לצורך דיווח או חישובים נוספים, ייתכן שעדיף להציג אותו כאפס. הפרמטר fill_value הופך זאת לקל.
# Using fill_value to replace NaN with 0
revenue_by_category_region_filled = pd.pivot_table(df,
values='Revenue',
index='Product_Category',
columns='Region',
aggfunc='sum',
fill_value=0)
print(revenue_by_category_region_filled)
פלט:
Region Asia Europe North America Product_Category Apparel 1125 625 0 Books 336 360 488 Electronics 13200 14550 29100
הטבלה כעת נקייה וקלה יותר לקריאה, במיוחד עבור קהל לא טכני.
עבודה עם מדדים מרובים (אינדקס היררכי)
מה אם אתם צריכים לקבץ לפי יותר מקטגוריה אחת בשורות? לדוגמה, בואו נפצל את המכירות לפי Region ולאחר מכן לפי Country בתוך כל אזור. אנו יכולים להעביר רשימה של עמודות לפרמטר index.
# Multi-level pivot table using a list for the index
multi_index_pivot = pd.pivot_table(df,
values='Revenue',
index=['Region', 'Country'],
aggfunc='sum',
fill_value=0)
print(multi_index_pivot)
פלט:
Revenue
Region Country
Asia China 488
India 1760
Japan 10860
Europe France 1020
Germany 14440
UK 1115
North America Canada 17800
USA 12058
Pandas יצרה אוטומטית MultiIndex בשורות. מבנה היררכי זה נהדר לצורך הסתעפות לתוך הנתונים שלכם ולראות קשרים מקוננים. ניתן להחיל את אותו היגיון על הפרמטר columns כדי ליצור עמודות היררכיות.
שימוש בפונקציות צבירה מרובות
לפעמים, סטטיסטיקת סיכום אחת אינה מספיקה. ייתכן שתרצו לראות גם את סך ההכנסות (סכום) וגם את גודל העסקה הממוצע (ממוצע) עבור כל קבוצה. אתם יכולים להעביר רשימה של פונקציות ל- aggfunc.
# Using multiple aggregation functions
multi_agg_pivot = pd.pivot_table(df,
values='Revenue',
index='Region',
aggfunc=['sum', 'mean', 'count'])
print(multi_agg_pivot)
פלט:
sum mean count
Revenue Revenue Revenue
Region
Asia 13108.000000 2184.666667 6
Europe 16575.000000 2762.500000 6
North America 29858.000000 4976.333333 6
פקודה יחידה זו נותנת לנו סיכום מקיף: סך ההכנסות, ההכנסה הממוצעת לעסקה ומספר העסקאות עבור כל אזור. שימו לב כיצד Pandas יוצר עמודות היררכיות כדי לשמור על הפלט מאורגן.
החלת פונקציות שונות על ערכים שונים
אפשר להיות עוד יותר גרעיניים. תארו לעצמכם שאתם רוצים לראות את סכום Revenue אבל את הממוצע של Units_Sold. אתם יכולים להעביר מילון ל- aggfunc כאשר המפתחות הם שמות העמודות ('ערכים') והערכים הם פונקציות הצבירה הרצויות.
# Different aggregations for different values
dict_agg_pivot = pd.pivot_table(df,
index='Region',
values=['Revenue', 'Units_Sold'],
aggfunc={
'Revenue': 'sum',
'Units_Sold': 'mean'
},
fill_value=0)
print(dict_agg_pivot)
פלט:
Revenue Units_Sold
Region
Asia 13108 17.833333
Europe 16575 8.166667
North America 29858 14.333333
רמת שליטה זו היא שהופכת את pivot_table() לכלי מוביל לניתוח נתונים מתוחכם.
חישוב סכומים כוללים עם margins
לצורך דיווח, לעתים קרובות חיוני שיהיו סכומי שורות ועמודות. הארגומנט margins=True מספק זאת ללא מאמץ נוסף.
# Adding totals with margins=True
revenue_with_margins = pd.pivot_table(df,
values='Revenue',
index='Product_Category',
columns='Region',
aggfunc='sum',
fill_value=0,
margins=True,
margins_name='Grand Total') # Custom name for totals
print(revenue_with_margins)
פלט:
Region Asia Europe North America Grand Total Product_Category Apparel 1125 625 0 1750 Books 336 360 488 1184 Electronics 13200 14550 29100 56850 Grand Total 14661 15535 29588 59784
Pandas מחשב אוטומטית את הסכום עבור כל שורה (סך ההכנסות לכל קטגוריית מוצרים בכל האזורים) ועבור כל עמודה (סך ההכנסות לכל אזור בכל הקטגוריות), בתוספת סכום כולל עבור כל הנתונים בפינה הימנית התחתונה.
מקרה שימוש מעשי: ניתוח מבוסס זמן
טבלאות ציר אינן מוגבלות לקטגוריות סטטיות. הן שימושיות להפליא לניתוח נתוני סדרות זמן. בואו נמצא את סך ההכנסות עבור כל חודש.
ראשית, עלינו לחלץ את החודש מעמודת 'Date' שלנו. אנחנו יכולים להשתמש ב- .dt accessor בפנדס בשביל זה.
# Extract month from the Date column
df['Month'] = df['Date'].dt.month_name()
# Pivot to see monthly revenue by product category
monthly_revenue = pd.pivot_table(df,
values='Revenue',
index='Month',
columns='Product_Category',
aggfunc='sum',
fill_value=0)
# Optional: Order the months correctly
month_order = ['January', 'February', 'March']
monthly_revenue = monthly_revenue.reindex(month_order)
print(monthly_revenue)
פלט:
Product_Category Apparel Books Electronics Month January 250 360 23100 February 795 794 24250 March 705 30 9500
טבלה זו נותנת לנו תצוגה ברורה של ביצועי המכירות של כל קטגוריה לאורך זמן, ומאפשרת לנו לזהות מגמות, עונתיות או חריגות בקלות.
pivot_table() לעומת groupby(): מה ההבדל?
זוהי שאלה נפוצה עבור אלה שלומדים Pandas. שתי הפונקציות קשורות קשר הדוק, ולמעשה, pivot_table() בנויה על גבי groupby().
groupby()היא פעולה כללית ובסיסית יותר. היא מקבצת נתונים על סמך קריטריונים מסוימים ואז מאפשרת לכם להחיל פונקציית צבירה. התוצאה היא בדרך כלל Pandas Series או DataFrame עם אינדקס היררכי, אך היא נשארת בפורמט 'ארוך'.pivot_table()היא כלי מיוחד שעושה group-by ואז מעצב מחדש את הנתונים. מטרתה העיקרית היא להפוך את הנתונים מפורמט ארוך לפורמט רחב, שלעתים קרובות קל יותר לקריאה על ידי בני אדם.
בואו נסקור שוב את הדוגמה הראשונה שלנו באמצעות groupby():
# Same result as our first pivot table, but using groupby
category_revenue_groupby = df.groupby('Product_Category')['Revenue'].sum()
print(category_revenue_groupby)
התוצאה היא Pandas Series ששקולה מבחינה תפקודית ל- DataFrame מטבלת הציר הראשונה שלנו. עם זאת, כאשר אתם מציגים מפתח קיבוץ שני (כמו 'Region'), ההבדל הופך לברור.
# Grouping by two columns
groupby_multi = df.groupby(['Product_Category', 'Region'])['Revenue'].sum()
print(groupby_multi)
פלט (Series עם MultiIndex):
Product_Category Region
Apparel Asia 1125
Europe 625
Books Asia 336
Europe 360
North America 488
Electronics Asia 13200
Europe 14550
North America 29100
Name: Revenue, dtype: int64
כדי לקבל את אותו פורמט 'רחב' כמו pivot_table(index='Product_Category', columns='Region'), תצטרכו להשתמש ב- groupby() ואחריו unstack():
# Replicating a pivot table with groupby().unstack()
groupby_unstack = df.groupby(['Product_Category', 'Region'])['Revenue'].sum().unstack(fill_value=0)
print(groupby_unstack)
זה מייצר את אותו פלט בדיוק כמו טבלת הציר שלנו עם עמודות. אז, אתם יכולים לחשוב על pivot_table() כקיצור דרך נוח עבור זרימת העבודה הנפוצה groupby().aggregate().unstack().
מתי להשתמש באיזה?
- השתמשו ב-
pivot_table()כאשר אתם רוצים פלט בפורמט רחב וקריא, במיוחד לצורך דיווח או יצירת טבלאות צולבות. - השתמשו ב-
groupby()כאשר אתם צריכים יותר גמישות, מבצעים חישובים ביניים בצינור עיבוד נתונים, או כאשר הפורמט הרחב והמעוצב מחדש אינו המטרה הסופית שלכם.
ביצועים ושיטות עבודה מומלצות
בעוד pivot_table() חזק, חשוב להשתמש בו ביעילות, במיוחד עם מערכי נתונים גדולים.
- סננו קודם, צרו ציר אחר כך: אם אתם צריכים לנתח רק קבוצת משנה של הנתונים שלכם (למשל, מכירות מהשנה האחרונה), סננו את ה- DataFrame לפני החלת טבלת הציר. זה מקטין את כמות הנתונים שהפונקציה צריכה לעבד.
- השתמשו בסוגים קטגוריים: עבור עמודות שאתם משתמשים בהן לעתים קרובות כאינדקסים או עמודות בטבלאות הציר שלכם (כמו 'Region' או 'Product_Category'), המירו אותן ל- 'category' dtype בפנדס. זה יכול להפחית באופן משמעותי את השימוש בזיכרון ולהאיץ את פעולות הקיבוץ.
df['Region'] = df['Region'].astype('category') - שמרו על זה קריא: הימנעו מיצירת טבלאות ציר עם יותר מדי אינדקסים ועמודות. בעוד שאפשר, טבלת ציר שרוחבה מאות עמודות ואורכה אלפי שורות יכולה להפוך לבלתי קריאה בדיוק כמו הנתונים הגולמיים המקוריים. השתמשו בה כדי ליצור סיכומים ממוקדים.
- הבינו את הצבירה: שימו לב לבחירה שלכם ב-
aggfunc. שימוש ב- 'sum' על מחירים אינו הגיוני, בעוד ש- 'mean' עשוי להיות מתאים יותר. ודאו תמיד שהצבירה שלכם תואמת לשאלה שאתם מנסים לענות עליה.
מסקנה: הכלי שלכם לסיכומים תובנתיים
הפונקציה pivot_table() של Pandas היא כלי הכרחי בארגז הכלים של כל אנליסט נתונים. היא מספקת דרך הצהרתית, אקספרסיבית וחזקה לעבור מנתונים מבולגנים ומפורטים לסיכומים נקיים ותובנתיים. על ידי הבנה ושליטה ברכיבי הליבה שלה - values, index, columns ו- aggfunc - ומינוף התכונות המתקדמות שלה כמו אינדקס רב-רמות, צבירות מותאמות אישית ושוליים, אתם יכולים לעצב מחדש את הנתונים שלכם כדי לענות על שאלות עסקיות מורכבות בכמה שורות קוד של פייתון.
בפעם הבאה שתתקלו במערך נתונים גדול, התנגדו לדחף לגלול בין שורות אינסופיות. במקום זאת, חשבו על השאלות שאתם צריכים לענות עליהן וכיצד טבלת ציר יכולה לעצב מחדש את הנתונים שלכם כדי לחשוף את הסיפורים החבויים בתוכם. ציר שמח!