HOWTO · Pandas

Pandas 中如何获取特定列满足给定条件的所有行的索引

我们可以使用简单的索引操作,np.where()函数和 query()方法来获取特定列满足给定条件的所有行的索引。

本页内容

要筛选 Pandas 列中符合条件的行,可以使用布尔索引,再读取筛选后 DataFrame 的 .index。这样得到的是用于标识行的索引标签,它们不一定等于行的数字位置。np.where() 可以返回条件数组中的匹配位置,而 DataFrame.query() 可以通过表达式筛选行,同时保留其索引标签。请根据后续步骤需要的结果选择方法。

使用布尔索引获取符合条件的行索引

像 df["Sales"] >= 300 这样的比较会生成一个布尔 Series,其值与 DataFrame 的各行对齐。将该 Series 放入 df[...] 中即可保留符合条件的行,然后读取 .index。如果需要把索引传给其他函数或显示出来,调用 .tolist() 可将其转换为普通 Python 列表。

运行以下示例:示例中的列名以及代码和输出中的标签仍为英文。

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 方法。传入一维布尔条件后,它会返回一个元组,其中包含一个数组,列出条件为真的位置。选择元组的第一个元素 [0],即可得到扁平的行位置数组。这些位置对应布尔数组,而不是 DataFrame 的索引标签;因此,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(...) 中,会得到一个包含元组数组的列表;这与扁平的位置列表不同。如果需要索引标签,则应使用筛选后 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 的索引标签。