filt=(~df['Age'].isnull())
df=df.loc[filt,:]
print(df)
程序之所以知道 filt
中的每个元素对应 df
中的每一行,是因为 pandas
库设计时就考虑到了这种需求,并在实现中做了对应的处理。具体来说,pandas
的 DataFrame
和 Series
对象在进行布尔索引时,会对齐索引(index),确保布尔序列正确地应用到数据框的行或列上。
工作原理
-
索引对齐:
pandas
使用索引(index)来对齐DataFrame
和Series
。当你对DataFrame
进行布尔索引时,pandas
会自动根据索引对齐布尔序列和数据框的行。
-
长度匹配:
- 在进行布尔索引时,
pandas
要求布尔序列的长度与数据框的行数相同。这样,每个布尔值就可以对应数据框中的一行。
- 在进行布尔索引时,
示例解析
假设你有一个 DataFrame
df
和一个布尔序列 filt
,它们的索引和长度如下:
import pandas as pd
import numpy as np
# 创建示例数据框
data = {
'Name': ['Alice', 'Bob', 'Charlie', 'David'],
'Age': [25, np.nan, 30, np.nan]
}
df = pd.DataFrame(data)
# 创建布尔值序列 filt
filt = ~df['Age'].isnull()
在这个示例中:
df
的索引是[0, 1, 2, 3]
filt
的索引也是[0, 1, 2, 3]
执行布尔索引
当你使用 loc
索引器进行布尔索引时:
df_filtered = df.loc[filt, :]
loc
索引器会将filt
中的布尔值与df
的索引进行对齐。- 因为
filt
的索引与df
的索引完全一致,且长度相同,每个布尔值自然对应df
中的每一行。
详细步骤
-
生成布尔序列
filt
:filt = ~df['Age'].isnull()
filt
是一个Series
,其索引与df
的行索引相同:0 True 1 False 2 True 3 False Name: Age, dtype: bool
-
使用
loc
索引器进行布尔索引:df_filtered = df.loc[filt, :]
loc
索引器将filt
与df
的行索引对齐,然后选择filt
中布尔值为True
的行:Name Age 0 Alice 25.0 2 Charlie 30.0
对齐机制
pandas
的索引对齐机制确保了即使索引顺序不同,布尔索引也能正确应用。考虑下面的例子:
# 重新索引示例
df = df.set_index([pd.Index([10, 11, 12, 13])])
# filt 的索引仍然是 [0, 1, 2, 3]
filt = pd.Series([True, False, True, False], index=[10, 11, 12, 13])
# 使用 loc 索引器进行布尔索引
df_filtered = df.loc[filt, :]
在这个例子中,即使索引不是默认的整数索引,pandas
仍然会基于索引对齐 filt
和 df
,确保布尔值正确应用:
Name Age
10 Alice 25.0
12 Charlie 30.0
通过这些机制,pandas
能够确保布尔序列正确地应用到 DataFrame
的行上,从而实现精确的布尔索引操作。