אילוק מול לוק בפנדות: מדריך עם דוגמאות

אחת מהדברים המטרידים שאנחנו מנסים להבין כשאנחנו לומדים את פנדס היא ההבחנה בין .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

ישנם שני דברים שחשוב לזכור כאן:

  1. הפלט כולל את השורה שצוינה ב־row_label_end. זה שונה ב־.iloc, אותו נכסף בהמשך.
  2. אנו משתמשים רק בזוג סוגריים מרובעים אחד, גם על אף שאנחנו רוצים לאחזר מספר שורות. אנו לא משתמשים ברשימה כדי לציין את השורות השונות, לכן שימוש בשני סוגריים מרובעים יחזיר 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 היא ברורה כעת. כדי ללמוד עוד, הנה צעדים הבאים המומלצים:

Source:
https://www.datacamp.com/tutorial/loc-vs-iloc