Pandas 中的 Iloc vs Loc:帶有示例的指南

當我們學習 Pandas 時,大家都試圖弄清楚的一件煩人的事情就是 .loc.iloc 之間的區別。

讓我們結束這種困惑,澄清這兩個方法之間的差異。我會提供很多例子,希望到這篇博客結尾時,這個區別會變得更加清晰。

在 Pandas 中,.loc 和 .iloc 是什麼?

.loc.iloc 都是 Pandas DataFrame 的重要屬性,並且都用於選擇特定的數據子集。它們的目的是訪問並使能夠操控 DataFrame 的特定部分,而不是整個 DataFrame。

特徵

.loc

.iloc

語法

df.loc[row_indexer, column_indexer]

df.iloc[row_indexer, column_indexer]

索引方法

基於標籤的索引

基於位置的索引

用於參考

行和列標籤(名稱)

行和列的數字索引(從0開始)

正如我們從表中看到的,語法看起來非常相似。不同之處在於我們如何使用row_indexercolumn_indexer參數。這是因為這兩種方法提供了不同的數據索引方法:.loc基於標籤名稱進行索引,而.iloc則以行和列的數字位置索引作為參數。

讓我們詳細檢查這兩種方法,首先從.loc開始。

使用 .loc:按標籤選擇

為了說明這些概念,讓我們考慮一個假設的客戶數據庫,這個數據庫由名為 df 的 DataFrame 表示,其中 Customer ID 代表行索引 i

客戶編號

姓名

國家

地區

年齡

C123

約翰·杜

美國

北美洲

67

C234

佩特拉·穆勒

德國

歐洲

51

C345

Ali Khan

Pakistan

Asia

19

C456

Maria Gonzalez

Mexico

North America

26

C567

David Lee

China

Asia

40

四種使用.loc來選擇行的主要方法,包括:

  • 選擇單行
  • 選擇多行
  • 選擇一組連續的行
  • 條件行選擇

使用.loc選擇單行

要選擇單行,我們使用要檢索的行標籤作為row_indexer。因此,語法如下:df.loc['row_label']。讓我們使用這個方法顯示我們的客戶Ali Khan的所有信息:

df.loc['C345']

C345

 

名稱

Ali Khan

國家

巴基斯坦

地區

亞洲

年齡

19

使用 .loc 選擇多行

如果我們想選擇不一定是連續的多行,我們必須將它們的行標籤列表作為 row_indexer 參數傳遞。這意味著我們需要使用兩對方括號:一個是常規的 .loc 語法,另一個是標籤列表。

這行 df.loc[['row_label_1', 'row_label_2']] 將返回列表中指定的 df 數據框的兩行。假設我們想知道不僅是 Ali Khan 的信息,還有 David Lee 的信息:

df.loc[['C345', 'C567']]

客戶ID

姓名

國家

地區

年齡

C345

阿里·汗

巴基斯坦

亞洲

19

C567

大衛·李

中國

亞洲

40

使用 .loc 選擇行的一部分

我們可以通過在中間加上冒號來傳遞第一行和最後一行的標籤來選擇行範圍: df.loc['row_label_start':'row_label_end']。我們可以這樣顯示我們的數據框的前四行:

df.loc['C123' : 'C456']

客戶ID

姓名

國家

地區

註冊日期

C123

約翰·多

美國

北美洲

67

C234

佩特拉·穆勒

德國

歐洲

51

C345

阿里·汗

巴基斯坦

亞洲

19

C456

瑪麗亞·岡薩雷斯

墨西哥

北美洲

26

這裡有兩件事需要記住:

  1. 輸出包括在row_label_end中指定的行。這與稍後會介紹的.iloc不同。
  2. 我們只使用一對方括號,即使我們想檢索多行。我們並不使用列表來指定各種行,因此使用兩對方括號會返回SyntaxError

使用.loc的行條件選擇

我們也可以根據條件表達式來返回行。我們可以根據是否滿足某個條件過濾所有行,並僅顯示滿足條件的行。

相應的語法是df.loc[conditional_expression],其中conditional_expression是有關特定列中允許值的陳述。

對於具有非數字數據的列(如姓名國家),語句只能使用等於或不等於運算符,因為值之間沒有順序。例如,我們可以返回所有不來自亞洲的客戶的行:

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

Petra Müller

C345

Ali Khan

C456

Maria Gonzalez

C567

David Lee

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']]

Customer ID

Name

Age

C123

John Doe

67

C234

Petra Müller

51

C345

阿里·汗

19

C456

瑪麗亞·岡薩雷斯

26

C567

大衛·李

40

使用 .loc 選取列的範圍

在兩個標籤之間使用冒號將選取這兩個指定列之間的所有列,範圍是包含結束列的,這意味著名為 col_end 的列也會在標準語法中被選取,語法如下:df.loc[:, 'col_start':'col_end']

如果我們對客戶的 姓名國家地區 感興趣,我們的代碼行可以是:

df.loc[:, 'Name':'Region']

客戶ID

姓名

國家

地區

C123

約翰·多

美國

北美洲

C234

Petra Müller

德國

歐洲

C345

Ali Khan

巴基斯坦

亞洲

C456

Maria Gonzalez

墨西哥

北美洲

C567

David Lee

中國

亞洲

使用.loc結合行和列的選擇

也可以指定row_indexercolumn_indexer。這可用於檢索單個信息,即DataFrame中的一個單元格。為此,我們使用語法df.loc['row_label', 'column_name']來指定一行和一列。

更有用的情況是返回一個專注於我們感興趣的行和列集的子DataFrame。可以使用方括號將兩個索引器都指定為列表,也可以使用冒號進行切片,甚至可以將其與行選擇的條件表達式結合使用。

以下是一個返回每位年齡超過30歲的客戶的NameCountryRegion的示例:

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 時的標籤字符串。要返回名為 df 的 DataFrame 的第一行,請輸入 df.iloc[0]

在我們的示例 DataFrame 中,這行代碼返回約翰·杜的信息:

df.iloc[0]

C123

 

Name

John Doe

Country

United States

Region

North America

Age

67

在`.iloc`中選擇多行

在`.iloc`中選擇多行與`.loc`中的操作方式相同—我們將行索引整數放入帶有方括號的列表中。語法如下:df.iloc[[0, 3, 4]]

我們客戶表中的相應輸出如下:

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

Petra Müller

德國

歐洲

51

C345

Ali Khan

巴基斯坦

亞洲

19

C456

Maria Gonzalez

墨西哥

北美洲

26

選擇使用.iloc選擇單列

使用 .iloc 選擇欄位的邏輯遵循我們到目前為止學到的內容。讓我們看看它如何運作於單一欄位、多個欄位和欄位切片。

就像使用 .loc 一樣,重要的是在我們能夠進入 column_indexer 之前,必須指定 row_indexer。要檢索 df 的第三欄對於每一行的值,我們輸入 df.iloc[:, 2]

因為 Region 是我們資料框中的第三欄,這行代碼將會返回它的值:

df.iloc[:, 2]

客戶編號

區域

C123

北美洲

C234

歐洲

C345

亞洲

C456

北美洲

C567

亞洲

使用 .iloc 選擇多個列

要選擇不一定連續的多列,我們可以再次輸入包含整數的列表作為 column_indexer。行 df.iloc[:, [0, 3]] 返回第一列和第四列。

在我們的情況下,顯示的信息是每位客戶的 NameAge

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]

客戶ID

國家

地區

C123

美國

北美洲

C234

德國

歐洲

C345

巴基斯坦

亞洲

C456

墨西哥

北美洲

C567

中國

亞洲

使用 .iloc 進行行和列的組合選擇

我們可以將學到的關於 .iloc 的內容整合起來,以組合行和列的選擇。同樣,可以返回單個單元格或子數據框。要返回第 3 行和第 4 列交叉處的單個單元格,我們輸入 df.iloc[2, 3]

就像使用 .loc 一樣,我們可以使用方括號將兩個索引器指定為列表,或者使用冒號作為切片。如果我們想使用條件表達式選擇行,技術上也可以使用 .iloc,但不建議這樣做。使用標籤名稱和 .loc 通常更直觀且不易出錯。

這最後一個範例顯示了我們的數據框中第一、第二和第五行的 國家地區年齡

df.iloc[[0,1,4], 1:4]

客戶 ID

國家

地區

年齡

C123

美國

北美洲

67

C234

德國

歐洲

51

C567

中國

亞洲

40

.iloc vs .loc: When to Use Which

通常情況下,一個簡單的準則取決於您對數據框的了解程度:

  • 當您知道行/列的標籤(名稱)時,請使用.loc
  • 當您知道行/列的整數位置時,請使用.iloc 當您知道行/列的整數位置時,請使用.iloc

某些情況下,根據其性質,要使用.loc.iloc更為適合。例如,使用整數進行行或列的迭代比使用標籤更容易且更直觀。正如我們已經提到的,基於列值條件過濾行的操作,使用列標籤名稱較少出錯。

偏好 .loc 的情況

偏好 .iloc 的情況

您的 DataFrame 具有有意義的索引/列名稱。

您正在按行/列的位置迭代。

您需要根據列值的條件進行篩選。

索引/列名對您的任務不重要。

KeyError、NameError 和 Index Error 使用 .loc 和 .iloc

讓我們看看可能出現的問題。在使用 .loc 時的一個常見問題是遇到 KeyError。當我們嘗試訪問不存在於我們 DataFrame 中的行或列標籤時,就會出現此錯誤。為了避免這種情況,我們必須始終確保我們使用的標籤是準確的,並且與 DataFrame 中現有的標籤匹配,並且要仔細檢查有無拼寫錯誤。

此外,使用 .loc 指定的標籤時,始終重要使用引號。忘記引號將返回一個 NameError

如果在使用.iloc時指定了超出DataFrame索引範圍的整數位置,則可能會出現IndexError。這種情況發生在您嘗試訪問的索引不存在時,這可能是因為它超出了DataFrame中行或列的數量,或者因為它是一個負值。為了防止此錯誤,請檢查DataFrame的尺寸並在有效範圍內使用適當的索引值。

結論

我希望這篇博客對您有所幫助,並且現在您應該清楚了.loc.iloc之間的區別。要瞭解更多,以下是一些不錯的下一步:

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