HOWTO · Pandas
Pandas 中如何獲取特定列滿足給定條件的所有行的索引
我們可以使用簡單的索引操作,np.where()函式和 query()方法來獲取特定列滿足給定條件的所有行的索引。
本頁內容
若要找出 Pandas 欄位符合條件的資料列,請使用布林索引篩選資料,再讀取篩選後 DataFrame 的 .index。這會傳回索引標籤,用來識別資料列,但不一定是資料列的數值位置。np.where() 可改為傳回條件陣列中的位置;DataFrame.query() 則會依運算式篩選資料列,同時保留索引標籤。請依照下一步所需的結果選擇方法。
使用布林索引取得符合條件的資料列索引
像 df["Sales"] >= 300 這樣的比較會建立一個布林 Series,其值會與 DataFrame 的資料列對齊。將這個 Series 放入 df[...],即可保留符合條件的資料列,接著讀取 .index。若要傳給其他函式或顯示時,使用一般 Python 清單較方便,可以呼叫 .tolist() 將索引轉成清單。
執行以下範例。範例程式碼及顯示的欄名與輸出維持英文:
本節中的程式碼以及顯示的標籤或輸出仍為英文。
import pandas as pd
df = pd.DataFrame(
{"Sales": [200, 300, 400, 200, 300, 300]},
index=[10, 11, 12, 13, 14, 15],
)
mask = df["Sales"] >= 300
matching_rows = df[mask]
print(mask.tolist())
print(matching_rows)
print(matching_rows.index.tolist())
遮罩會標示每個 Sales 值大於或等於 300 的資料列。matching_rows.index 包含保留下來的資料列索引標籤;呼叫 .tolist() 會將它們轉成標籤清單。此例刻意讓索引標籤與資料列位置不同,方便看出兩者的差異。
了解索引標籤與資料列位置
索引標籤是儲存在 DataFrame 索引中的識別值;資料列位置則是資料列目前順序中的零起始位移。使用預設的 RangeIndex 時,標籤看起來常像是位置,但那只是恰好相同。篩選後的 DataFrame 會保留原有標籤,不會重新為資料列編號。需要這些識別值時,請使用 .index;若某個 API 需要目前陣列或資料列順序中的位移,則應使用位置結果。
使用 np.where() 取得符合條件的資料列位置
np.where() 是 NumPy 函式,不是 Pandas 方法。傳入一維布林條件後,它會傳回一個 tuple,其中包含符合條件之位置的陣列。選取 tuple 的第一個元素 [0],即可取得一維的位置陣列。這些是布林陣列中的位置,不是 DataFrame 的索引標籤,因此使用自訂索引時,兩者可能不同。
執行以下範例。範例程式碼及顯示的欄名維持英文:
本節中的程式碼以及顯示的標籤或輸出仍為英文。
import numpy as np
import pandas as pd
df = pd.DataFrame({"Sales": [200, 300, 400, 200, 300, 300]}, index=[10, 11, 12, 13, 14, 15])
mask = df["Sales"] >= 300
positions = np.where(mask.to_numpy())[0]
print(positions.tolist())
若明確需要符合條件的位置,請使用 np.where(mask.to_numpy())[0]。將整個呼叫包在 list(...) 中,會得到一個包含 tuple 陣列的清單;這與直接取得位置的一維清單不同。若需要索引標籤,請改用篩選後 DataFrame 的 .index。
使用 DataFrame.query() 篩選資料列並取得索引
DataFrame.query() 會依欄位名稱解析字串運算式,並以 DataFrame 形式傳回符合條件的資料列。讀取結果的 .index 可取得原有索引標籤;若需要清單,則可使用 .tolist()。運算式中的欄位名稱與比較條件應和 DataFrame 一致;此處的條件會選出 Sales 值等於 300 的資料列。
執行以下範例。範例程式碼及顯示的欄名與輸出維持英文:
本節中的程式碼以及顯示的標籤或輸出仍為英文。
import pandas as pd
df = pd.DataFrame({"Sales": [200, 300, 400, 200, 300, 300]}, index=[10, 11, 12, 13, 14, 15])
labels = df.query("Sales == 300").index.tolist()
print(labels)
若要從運算式篩選結果取得索引標籤,請使用 df.query("Sales == 300").index。若要取得布林條件符合的位置,請使用 np.where(condition)[0]。需要同時取得符合條件的資料列及其標籤時,布林索引是直接的選擇。這三種寫法回答的問題彼此相關,但只有第一種與第三種會傳回 DataFrame 的索引標籤。