אחת מהדברים המטרידים שאנחנו מנסים להבין כשאנחנו לומדים את פנדס היא ההבחנה בין .loc
ל-.iloc
.
נניח סוף לבלבול הזה ונבהיר את ההבדל בין שתי השיטות הללו. אעניק plenty of examples, ואני מקווה שההבחנה תהיה הרבה יותר ברורה עד סוף הבלוג הזה.
מה הם .loc ו-.iloc בפנדס?
גם .loc
וגם .iloc
הם תכונות חיוניות של DataFrames בפנדס, ושניהם משמשים לבחירת תתי קבוצות ספציפיות של נתונים. מטרתם היא לגשת ולאפשר מניפולציה על חלק ספציפי של ה-DataFrame במקום על כל ה-DataFrame.
תכונה |
.loc |
.iloc |
תחביר |
df.loc[row_indexer, column_indexer] |
df.iloc[row_indexer, column_indexer] |
שיטת אינדקסציה |
אינדקסציה על פי תווית |
אינדקסציה על פי מיקום |
משמש להתייחסות |
תוויות שורות ועמודות |
אינדקסים מספריים של שורות ועמודות (מתחילים מ-0) |
כפי שניתן לראות מהטבלה, התחביר נראה דומה מאוד. ההבדל הוא באופן שבו אנו משתמשים בארגומנטים row_indexer
ו־column_indexer
. זה כיוון ששתי השיטות מציעות גישות שונות לאינדקות הנתונים: בעוד .loc
אינדקסים על פי שמות תוויות, .iloc
מקבל אינדקס של מיקום מספרי של שורות ועמודות כארגומנטים.
בואו לבחון כל אחת מהשיטות בפרט, מתחילים עם .loc
.
שימוש ב-.loc: בחירת תוויות
להמחשה של המושגים, נבחן בסיטונאות בדיוק בסיס נתונים לקוחות בדימוי זה של DataFrame הנקרא df
, עם Customer ID
מייצג את השורה האינדקסית:
Customer ID |
Name |
Country |
Region |
Age |
C123 |
John Doe |
United States |
North America |
67 |
C234 |
Petra Müller |
Germany |
Europe |
51 |
C345 |
עלי חאן |
פקיסטן |
אסיה |
19 |
C456 |
מריה גונזלס |
מקסיקו |
צפון אמריקה |
26 |
C567 |
דיויד לי |
סין |
אסיה |
40 |
There יש ארבעה דרכים עיקריות לבחור שורות עם .loc
. אלו כוללות:
- בחירת שורה יחידה
- בחירת שורות מרובות
- בחירת קטע של שורות
- בחירת שורה בהתאם לתנאי
בחירת שורה יחידה באמצעות .loc
כדי לבחור שורה יחידה, אנו משתמשים בתווית השורה שברצוננו לקבל בתור row_indexer
. לפיכך, התחביר נראה כך: df.loc['row_label']
. בואו נשתמש בזה כדי להציג את כל המידע על הלקוח שלנו, עלי חאן:
df.loc['C345']
C345 |
|
שם |
עלי חאן |
מדינה |
פקיסטן |
אזור |
אסיה |
גיל |
19 |
בחירת שורות מרובות באמצעות .loc
אם רוצים לבחור שורות מרובות שאינן בהכרח עוקבות זו אחר זו, עלינו להעביר רשימה של תוויות השורות שלהם כארגומנט row_indexer
. כלומר, עלינו להשתמש לא רק בזוג אחד של סוגריים מרובעים: אחד עבור תחביר הרגיל של .loc
ואחד עבור רשימת התוויות.
השורה df.loc[['row_label_1', 'row_label_2']]
תחזיר את שתי השורות של מסגרת הנתונים df
שצוינו ברשימה. נניח שרצינו לדעת לא רק את המידע על עלי חאן אלא גם על דיוויד לי:
df.loc[['C345', 'C567']]
מספר לקוח |
שם |
מדינה |
אזור |
גיל |
C345 |
עלי חאן |
פקיסטן |
אסיה |
19 |
C567 |
דיויד לי |
סין |
אסיה |
40 |
בחירת חתיכת שורות באמצעות .loc
נוכל לבחור טווח של שורות על ידי העברת התוויות של השורה הראשונה והאחרונה עם נקודתיים ביניהן: df.loc['row_label_start':'row_label_end']
. נוכל להציג את ארבע השורות הראשונות של ה-DataFrame שלנו כך:
df.loc['C123' : 'C456']
מספר לקוח |
שם |
מדינה |
אזור |
תאריך רישום |
C123 |
ג'ון דו |
ארצות הברית |
צפון אמריקה |
67 |
C234 |
פטרה מולר |
גרמניה |
אירופה |
51 |
C345 |
עלי חאן |
פקיסטן |
אסיה |
19 |
C456 |
מריה גונזלס |
מקסיקו |
צפון אמריקה |
26 |
ישנם שני דברים שחשוב לזכור כאן:
- הפלט כולל את השורה שצוינה ב־
row_label_end
. זה שונה ב־.iloc
, אותו נכסף בהמשך. - אנו משתמשים רק בזוג סוגריים מרובעים אחד, גם על אף שאנחנו רוצים לאחזר מספר שורות. אנו לא משתמשים ברשימה כדי לציין את השורות השונות, לכן שימוש בשני סוגריים מרובעים יחזיר
SyntaxError
.
בחירת תנאים של שורות באמצעות .loc
אנו יכולים גם להחזיר שורות בהתבסס על ביטוי תנאי. אנו יכולים לסנן את כל השורות לפי אם הן עומדות בתנאי מסוים ולהציג רק את אלה שעושות זאת.
התחביר התואם הוא df.loc[ביטוי_תנאי]
, עם ה־conditional_expression
היוה עימוד על ערכים המותרים בעמודה מסוימת.
לעמודות עם נתונים לא נומריים (כמו Name
או Country
), ההצהרה יכולה להשתמש רק באופרטור שווה או לא שווה, מאחר שאין סדר בין הערכים. לדוגמה, נוכל, למשל, להחזיר את כל השורות של לקוחות שאינם מאסיה:
df.loc[df['Region'] != 'Asia']
מספר לקוח |
שם |
מדינה |
אזור |
גיל |
C123 |
ג'ון דו |
ארצות הברית |
צפון אמריקה |
67 |
C234 |
פטרה מולר |
גרמניה |
אירופה |
51 |
C456 |
מריה גונזלס |
מקסיקו |
צפון אמריקה |
26 |
בחירת עמודה יחידה באמצעות .loc
כדי לבחור עמודות, עלינו לציין את הארגומנט column_indexer
, שבא אחרי הארגומנט row_indexer
. אם רוצים לציין רק את column_indexer
, עלינו לסמן בדרך כלשהי שנרצה להחזיר את כל השורות ולסנן רק על העמודות. בואו נראה איך אפשר לעשות זאת!
בחירת עמודה יחידה ניתן לעשות על ידי ציון column_indexer
עם התווית של העמודה הרלוונטית. כדי לקבל את כל השורות, עלינו לציין את row_indexer
עם נקודתיים פשוטה. אנו מגיעים לסינטקס שנראה כמו זה: df.loc[:, 'column_name']
.
בואו נציג את השם
של כל לקוח:
df.loc[:, 'Name']
מס' לקוח |
שם |
C123 |
ג'ון דו |
C234 |
פטרה מולר |
C345 |
עלי חאן |
C456 |
מריה גונזלס |
C567 |
דיויד לי |
Selecting multiple columns using .loc
Similar to selecting multiple rows, we need to pass a list of column labels if we want to return multiple columns of a DataFrame that do not necessarily follow each other in order: df.loc[:, [col_label_1, 'col_label_2']]
.
Assuming we wanted to add all customers’ Age
to our last output, it would work like this:
df.loc[:, ['Name', 'Age']]
מזהה לקוח |
שם |
גיל |
C123 |
ג'ון דו |
67 |
C234 |
פטרה מולר |
51 |
C345 |
עלי חאן |
19 |
C456 |
מריה גונזלס |
26 |
C567 |
דוד לי |
40 |
בחירת חתיכת עמודות באמצעות .loc
שימוש בנקודתיים בין השמות של שני עמודות יבחר את כל העמודות בטווח הסדר בין שתי העמודות המצוינות. זה כולל את העמודה האחרונה, כלומר העמודה בשם col_end
תיבחר גם בסינטקס הסטנדרטי, שהוא הבא: df.loc[:, 'col_start':'col_end']
.
אם היינו מעוניינים בשם
, מדינה
ואזור
של הלקוחות שלנו, שורת הקוד שלנו יכולה להיות:
df.loc[:, 'Name':'Region']
מספר זיהוי לקוח |
שם |
מדינה |
אזור |
C123 |
ג'ון דו |
ארצות הברית |
צפון אמריקה |
C234 |
פטרה מילר |
גרמניה |
אירופה |
C345 |
עלי חאן |
פקיסטן |
אסיה |
C456 |
מריה גונזלס |
מקסיקו |
צפון אמריקה |
C567 |
דיוויד לי |
סין |
אסיה |
שילוב בחירת שורות ועמודות באמצעות .loc
כמו כן, ניתן לציין כאן את row_indexer
ואת column_indexer
. ניתן להשתמש בזה כדי לקבל מידע יחיד, במובן של תא אחד מתוך DataFrame. כדי לעשות זאת, אנו מציינים שורה אחת ועמודה אחת באמצעות התחביר df.loc['row_label', 'column_name']
.
המקרה המועיל יותר הוא להחזיר תת-DataFrame שמתמקד בדיוק בסט השורות והעמודות שאנו מעוניינים בהם. ניתן לציין את שני ה-indexers כרשימות באמצעות סוגריים מרובעים, או כקטע באמצעות נקודה וגם לשלב אותו עם ביטוי תנאי לבחירת השורות.
הנה דוגמה אחת להחזרת השדות Name
, Country
ו-Region
של כל לקוח שהגיל שלו מעל 30:
df.loc[df['Age'] > 30, 'Name':'Region']
מספר לקוח |
שם |
מדינה |
אזור |
C123 |
ג'ון דו |
ארצות הברית |
צפון אמריקה |
C234 |
פטרה מולר |
גרמניה |
אירופה |
C567 |
דיויד לי |
סין |
אסיה |
בשימוש ב-.iloc: בחירה לפי עמדה מספרית
.iloc
בוחר לפי עמדה במקום לפי תווית. זוהי התחביר האקראי לשימוש ב-.iloc
: df.iloc[row_indexer, column_indexer]
. ישנם שני דברים מיוחדים להסתכל עליהם:
- ספירה החל מ-0: השורה והעמודה הראשונים נמצאים באינדקס 0, השני באינדקס 1, וכן הלאה.
- הארכתיות של סופי טווח: בעת שימוש בחתיכה, השורה או העמודה שמסומנת מאחורי הנקודתיים אינה כלולה בבחירה.
בחירת שורה יחידה באמצעות .iloc
ניתן לבחור שורה יחידה על ידי שימוש במספר השורה כאינדקס השורה כ-row_indexer
. איננו זקוקים לציון סימני מרכאות מאחר ואנו מכניסים מספר שלם ולא מחרוזת תווית כפי שעשינו עם .loc
. כדי להחזיר את השורה הראשונה של DataFrame בשם df
, הזינו df.iloc[0]
.
בדוגמת ה-DataFrame שלנו, שורת הקוד הזו מחזירה את המידע על ג'ון דו:
df.iloc[0]
C123 |
|
Name |
John Doe |
Country |
United States |
Region |
North America |
Age |
67 |
Selecting multiple rows using .iloc
Selecting multiple rows works in .iloc
as it does in .loc
—we enter the row index integers in a list with squared brackets. The syntax looks like this: df.iloc[[0, 3, 4]]
.
The respective output in our customer table can be seen below:
df.iloc[[0, 3, 4]]
Customer ID |
Name |
Country |
Region |
Age |
C123 |
John Doe |
ארצות הברית |
צפון אמריקה |
67 |
C456 |
מריה גונזאלס |
מקסיקו |
צפון אמריקה |
26 |
C567 |
דיויד לי |
סין |
אסיה |
40 |
בחירת קטע של שורות באמצעות .iloc
עבור בחירת קטע של שורות, אנו משתמשים בנקודתיים בין שני מספרים אינדקס של שורות מסוימות. עכשיו, עלינו להתייחס לאפסיות שצוינו מראש.
נוכל לקחת את השורה df.iloc[1:4]
כדוגמה להמחשה של המושג הזה. האינדקס מספר 1 משמעו שורה השנייה, ולכן הקטע שלנו מתחיל משם. המספר השלם 4 מייצג את השורה החמישית – אך מאחר ש .iloc
אינו כולל לבחירת קטע, פלט שלנו יכלול את כל השורות עד לפני האחרונה מזו. לכן, הוא יחזיר את השורות השנייה, השלישית והרביעית.
בואו נוכיח שהשורה עובדת כפי שצריך:
df.iloc[1:4]
מזהה לקוח |
שם |
מדינה |
אזור |
גיל |
C234 |
פטרה מולר |
גרמניה |
אירופה |
51 |
C345 |
עלי חאן |
פקיסטן |
אסיה |
19 |
C456 |
מריה גונזלס |
מקסיקו |
צפון אמריקה |
26 |
בחירת עמודה יחידה באמצעות .iloc
הלוגיקה של בחירת עמודות באמצעות .iloc
עוקבת אחר מה שלמדנו עד כה. נראה איך זה עובד עבור עמודות יחידות, מרובות וחתכי עמודות.
כמו עם .loc
, חשוב לציין את row_indexer
לפני שנוכל להמשיך ל column_indexer
. כדי לקבל את הערכים בעמודה השלישית של df
עבור כל שורה, אנו מזינים df.iloc[:, 2]
.
מכיוון ש- Region
היא העמודה השלישית במבנה הנתונים שלנו, זה יוחזר כתוצאה מהשורה הזו:
df.iloc[:, 2]
מס' לקוח |
אזור |
C123 |
צפון אמריקה |
C234 |
אירופה |
C345 |
אסיה |
C456 |
צפון אמריקה |
C567 |
אסיה |
בחירת עמודות מרובות באמצעות .iloc
כדי לבחור עמודות מרובות שאינן בהכרח רצופות, אפשר שוב להזין רשימה המכילה מספרים שלמים כאינדקסי עמודה. השורה df.iloc[:, [0, 3]]
מחזירה את העמודות הראשונה והרביעית.
במקרה שלנו, המידע המוצג הוא הName
וכן הAge
של כל לקוח:
df.iloc[:, [0, 3]]
מספר לקוח |
שם |
גיל |
C123 |
ג'ון דו |
67 |
C234 |
פטרה מולר |
51 |
C345 |
עלי חאן |
19 |
C456 |
מריה גונזלס |
26 |
C567 |
דיויד לי |
40 |
בחירת קטע של עמודות באמצעות .iloc
לבחירת קטע באמצעות .iloc
, הלוגיקה של column_indexer
עוקבת אחר הלוגיקה של row_indexer
. העמודה שמיוצגת על ידי המספר אחרי הנקודתיים אינה כלולה בפלט. כדי לאחזר את העמודות השנייה והשלישיות, הקוד צריך להיראות כך: df.iloc[:, 1:3]
.
השורה הבאה מחזירה את כל המידע הגיאוגרפי שיש לנו על לקוחותינו:
df.iloc[:, 1:3]
מזהה לקוח |
מדינה |
אזור |
C123 |
ארצות הברית |
צפון אמריקה |
C234 |
גרמניה |
אירופה |
C345 |
פקיסטן |
אסיה |
C456 |
מקסיקו |
צפון אמריקה |
C567 |
סין |
אסיה |
שילוב של בחירת שורה ועמודה באמצעות .iloc
ניתן לשלב את מה שלמדנו על .iloc
כדי לשלב בחירת שורה ועמודה. שוב, ניתן להחזיר תא יחיד או תת-DataFrame. כדי להחזיר את התא היחיד בחיתוך של שורה 3 ועמודה 4, אנו מזינים df.iloc[2, 3]
.
כמו עם .loc
, ניתן לציין שני אינדקסרים כרשימות באמצעות הסוגריים המרובעים, או כגזירה באמצעות הנקודה. אם רוצים לבחור שורות באמצעות ביטויים תנאי, זה אפשרי טכנית עם .iloc
כמו גם, אבל לא מומלץ. שימוש בשמות התווית וב-.loc
כללית יותר אינטואיטיבית ופחות נוטה לשגיאות.
דוגמה אחרונה מציגה את מדינה
, אזור
ו-גיל
עבור השורה הראשונה, השנייה והחמישית ב-DataFrame שלנו:
df.iloc[[0,1,4], 1:4]
מזהה לקוח |
מדינה |
אזור |
גיל |
C123 |
ארצות הברית |
צפון אמריקה |
67 |
C234 |
גרמניה |
אירופה |
51 |
C567 |
סין |
אסיה |
40 |
.iloc vs .loc: מתי להשתמש בכל אחת
בדרך כלל, יש כלל פשוט שבו בחירת השיטה תלויה בידע שלך על המסד נתונים:
- השתמש ב־
.loc
כאשר אתה מכיר את התוויות (שמות) של השורות/עמודות. - השתמש ב־
.iloc
כאשר אתה יודע את תפקידיהם השלם של השורות/עמודות.
קיימות תרחישים שמעדיפים את .loc
או .iloc
מאופייהם. לדוגמה, סיבות כמו לעבור על שורות או עמודות יתר נוח ואינטואיטיבי באמצעות מספרים מאשר באמצעות תוויות. כפי שכבר ציינו, סינון שורות על פי תנאים על ערכי עמודה פחות נוטה לשגיאות בשימוש בשמות תוויות העמודות.
תרחישים המעדיפים .loc |
תרחישים המעדיפים .iloc |
למסגרת הנתונים שלך ישנם שמות מובנים לאינדקס/עמודות. |
אתה עובר על שורות/עמודות לפי המיקום שלהן. |
עליך לסנן על פי תנאים על ערכי העמודה. |
שמות האינדקס/העמודה אינם רלוונטיים למשימתך. |
KeyError, NameError, ו-Index Error עם .loc ו-.iloc
בואו נבחן בעיות אפשריות. בעיה נפוצה כאשר משתמשים ב-.loc
היא להתמודד עם KeyError
. השגיאה הזו מתרחשת כאשר אנו מנסים לגשת לתווית שורה או עמודה שאינם קיימים ב-DataFrame שלנו. כדי למנוע את זה, עלינו תמיד לוודא שהתוויות שאנו משתמשים בהן הן מדויקות ושהן תואמות לתוויות הקיימות ב-DataFrame שלך ולבדוק פעמיים בשביל טעויות כתיב.
בנוסף, חשוב תמיד להשתמש בגרשיים לתוויות שנציינו באמצעות .loc
. לשכוח מהן יחזיר NameError
.
יכול להתרחש IndexError
כאשר משתמשים ב-.iloc
ומציינים עמדת מספר שהיא מחוץ לטווח החוקי של אינדקסים במסד הנתונים שלנו. זה קורה כאשר האינדקס שאת/ה מנסה לגשת אליו איננו קיים, בגלל שהוא מעבר למספר השורות או העמודות במסד הנתונים שלך, או בגלל שהוא ערך שלילי. כדי למנוע שגיאה זו, יש לבדוק את ממדי מסד הנתונים שלך ולהשתמש בערכי אינדקס מתאימים בתוך הטווח החוקי.
מסקנה
אני מקווה שהבלוג הזה היה מועיל וההבחנה בין .loc
ל-.iloc
היא ברורה כעת. כדי ללמוד עוד, הנה צעדים הבאים המומלצים: