布尔系列键将重新编制索引以匹配DataFrame索引

Che*_*eng 36 python pandas

这是我遇到错误的方式:

df.loc[a_list][df.a_col.isnull()]
Run Code Online (Sandbox Code Playgroud)

类型a_listInt64Index,它包含行索引列表.所有这些行索引都属于df.

df.a_col.isnull()部分是我需要过滤的条件.

如果我单独执行以下命令,我不会收到任何警告:

df.loc[a_list]
df[df.a_col.isnull()]
Run Code Online (Sandbox Code Playgroud)

但如果我把它们放在一起df.loc[a_list][df.a_col.isnull()],我会得到警告信息(但我可以看到结果):

布尔系列键将重新编制索引以匹配DataFrame索引

这个错误消息的含义是什么?它会影响它返回的结果吗?

Ian*_*anS 47

尽管有警告,您的方法仍然有效,但最好不要依赖隐含的,不明确的行为.

解决方案1,在a_list布尔掩码中选择索引:

df[df.index.isin(a_list) & df.a_col.isnull()]
Run Code Online (Sandbox Code Playgroud)

解决方案2,分两步完成:

df2 = df.loc[a_list]
df2[df2.a_col.isnull()]
Run Code Online (Sandbox Code Playgroud)

解决方案3,如果你想要一个单行,请使用这里找到的技巧:

df.loc[a_list].query('a_col != a_col')
Run Code Online (Sandbox Code Playgroud)

警告来自这样的事实:布尔向量df.a_col.isnull()是长度df,而df.loc[a_list]长度是a_list,即更短.因此,有些指数df.a_col.isnull()不在df.loc[a_list].pandas做的是在与调用数据帧相同的索引上重新索引布尔向量.实际上,它来自df.a_col.isnull()对应于索引的值a_list.这是有效的,但行为是隐含的,并且可能在将来很容易改变,因此这就是警告的内容.

  • 当使用在另一个数据帧上计算的布尔掩码或在同一数据帧中的不同视图查询一个数据帧时,也会发生此警告. (4认同)

cot*_*ail 22

如果您收到此警告,请使用.loc[]而不是[]抑制此警告。1

df.loc[boolean_mask]           # <--------- OK
df[boolean_mask]               # <--------- warning
Run Code Online (Sandbox Code Playgroud)

对于OP中的特定情况,您可以链接.loc[]索引器:

df.loc[a_list].loc[df['a_col'].isna()]
Run Code Online (Sandbox Code Playgroud)

and或使用inside链接所有条件query()

# if a_list is a list of indices of df
df.query("index in @a_list and a_col != a_col")

# if a_list is a list of values in some other column such as b_col
df.query("b_col in @a_list and a_col != a_col")
Run Code Online (Sandbox Code Playgroud)

&或使用inside链接所有条件[](如 @IanS 的帖子中所示)。


如果发生此警告

  • 布尔掩码的索引与其正在过滤的数据帧的索引的顺序不同。

    df = pd.DataFrame({'a_col':[1, 2, np.nan]}, index=[0, 1, 2])
    m1 = pd.Series([True, False, True], index=[2, 1, 0])
    df.loc[m1]       # <--------- OK
    df[m1]           # <--------- warning
    
    Run Code Online (Sandbox Code Playgroud)
  • 布尔掩码的索引是它正在过滤的数据帧索引的超集。例如:

    m2 = pd.Series([True, False, True, True], np.r_[df.index, 10])
    df.loc[m2]       # <--------- OK
    df[m2]           # <--------- warning
    
    Run Code Online (Sandbox Code Playgroud)

1:如果我们查看[]和的源代码loc[],从字面上看,当布尔掩码的索引是数据帧索引的(弱)超集时,唯一的区别是显示此警告(通过方法)和不[]显示此警告。_getitem_bool_arrayloc[]