pandas 布尔系列键将被重新索引以匹配DataFrame索引

2ledvvac  于 2023-05-05  发布在  其他
关注(0)|答案(3)|浏览(168)

以下是我遇到警告的方式:

df.loc[a_list][df.a_col.isnull()]

a_list的类型是Int64Index,它包含一个行索引列表。所有这些行索引都属于df
df.a_col.isnull()部分是我进行过滤所需的条件。
如果我单独执行以下命令,我不会收到任何警告:

df.loc[a_list]
df[df.a_col.isnull()]

但是如果我把它们放在一起df.loc[a_list][df.a_col.isnull()],我会得到警告消息(但我可以看到结果):
布尔系列键将被重新索引以匹配DataFrame索引
此警告消息的含义是什么?是否会影响返回的结果?

vuv7lop3

vuv7lop31#

尽管有警告,你的方法还是会起作用的,但最好不要依赖于隐含的、不明确的行为。

方案1,将a_list中的索引选择为布尔掩码:

df[df.index.isin(a_list) & df.a_col.isnull()]

方案2,分两步进行:

df2 = df.loc[a_list]
df2[df2.a_col.isnull()]

解决方案3,如果你想要一行,使用一个技巧找到here

df.loc[a_list].query('a_col != a_col')

警告来自布尔向量df.a_col.isnull()的长度为df,而df.loc[a_list]的长度为a_list,即因此,df.a_col.isnull()中的一些索引不在df.loc[a_list]中。
pandas所做的是在调用 Dataframe 的索引上重新索引布尔序列。实际上,它从df.a_col.isnull()中获取对应于a_list中索引的值。这是可行的,但是行为是隐含的,并且在将来很容易改变,所以这就是警告的内容。

oknrviil

oknrviil2#

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

df.loc[boolean_mask]           # <--------- OK
df[boolean_mask]               # <--------- warning

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

df.loc[a_list].loc[df['a_col'].isna()]

或在query()中使用and链接所有条件:

# 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")

或者在[]中使用&链接所有条件(如@IanS的帖子)。
如果出现以下情况,则会出现此警告

  • 布尔掩码的索引不是与它正在过滤的 Dataframe 的索引的顺序相同
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
  • 布尔掩码的索引是它正在过滤的 Dataframe 的索引的超集。例如:
m2 = pd.Series([True, False, True, True], np.r_[df.index, 10])
df.loc[m2]       # <--------- OK
df[m2]           # <--------- warning

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

jyztefdp

jyztefdp3#

在遇到这个页面时,我通过查询完整的 Dataframe 收到了同样的错误,但使用的结果对子数据。
创建一个数据子集并存储在变量sub_df中:

sub_df = df[df['a'] == 1]
sub_df = sub_df[df['b'] == 1] # Note "df" hiding here

解决方案:
确保每次使用相同的 Dataframe (在我的例子中,只有sub_df):

# Last line should instead be:
sub_df = sub_df[sub_df['b'] == 1]

相关问题