pandas boolean index问题
背景
最近在用pandas的布尔索引(boolean index)时遇到一个问题,当时看到错误的时候是一脸懵,错误如下:
IndexingError: Unalignable boolean Series provided as indexer (index of the boolean Series and of the indexed object do not match
按照这个错误检索发现,引起这个错误的场景不止一种。
场景复现
下面用简单的例子复现一下错误:
有一个原始数据帧df,一个从df中按某种条件抽取(也是布尔索引)的训练数据帧train_df,还有一个预测结果数据帧pred。
# 原始数据帧
df = pd.DataFrame(
{'id':range(1,11),
'values':range(101,111)
}
)
# 训练数据帧
train_ids = [1,3,5,6,7]
train_df = df[df['id'].isin(train_ids)]
# 预测结果数据帧
pred = pd.DataFrame({'result':[1,0,1,0,1]})
mask = pred.loc[:,'result'] == 1
最终目的是从训练数据帧中提取出预测结果为1的数据,我就按往常的布尔索引逻辑,把上面的mask作为布尔序列来提取,如下:
train_df[mask]
然后就报了上面那个错误,大体意思就是提供的布尔序列和索引不匹配。我把关注点一直放在官方文档中提到的长度上,所以始终没想到错误的根因在哪。
A boolean array of the same length as the axis being sliced
解决方案
检索了很多相同错误的帖子,下面这篇给了灵感:
python-pandas-core-indexing-indexingerror-unalignable-boolean-series-key-provid
它的场景是列名与boolean Series不能对齐,给出的方案是将boolean Series变成boolean NumPy array。
这个方法,对我的场景也有效,即:
train_df[mask.values]
原因
回过头再看,容易发现问题所在:
训练数据帧train_df的索引并不是[0-4],而是[0,2,4,5,6]。
因此train_df的索引和pred为1的序列是匹配不了的。
换句话说,pandas布尔索引对待boolean Series和boolean NumPy array的匹配逻辑并不相同。具体有何不同就需要深入源码层面去分析了,有兴趣的可以自己看看。
总结
当你使用pandas布尔索引时,如果是同一个df的表达式产生的boolean Series不会出问题。
但用另一个顺序和长度一致的df产生的boolean Series来索引,可能会不匹配。这种情况需要将Series转成array来索引。
更多推荐
所有评论(0)