Pandas 报错 Unalignable boolean Series provided as indexer 的解决方法
Pandas 报错 Unalignable boolean Series provided as indexer 的解决方法前言改 bug分析第一步第二步解决我的问题解决方案通用解决方案结尾前言最近本菜鸡在 批量处理 数据的时候出现了问题,场景是:批量获得数据,判断是否在指定 DataFrame 中,如果不在,则 存入,否则,读取 ,但是写好多线程后出现了问题,于是写下本篇文章来记录一下出现问题的
前言
最近本菜鸡在 批量处理
数据的时候出现了问题,场景是:批量获得数据,判断是否在指定 DataFrame
中,如果不在,则 存入
,否则,读取
,但是写好多线程后出现了问题,于是写下本篇文章来记录一下出现问题的原因及解决方法。
- 偷偷说一句:如果对我的文章满意的话可不可以给我
点个赞
,点个收藏
,点个关注
,评论一下
。 - 一定要
看到最后
并且参加投票
哦。 Let's do it !!!
改 bug
报错如下(因为已经解决了,不想,准确来说 不敢,再动我的代码,所以就不截图了):
Unalignable boolean Series provided as indexer (index of the boolean Series and of the indexed object do not match).
用 百度翻译 一下,也就是说:
作为索引器提供的不可对齐布尔序列(布尔序列的索引和索引对象的索引不匹配)。
我看了一下报错所在的行,这一行是:
if df[df['en' == kw].empty
我的本意是想判断 df
中是否有数据的 en
这一列的值等于给定的 kw
,按理说是没有问题的,运行一次也是没有问题,可是开了多线程以后会有问题呢?
分析
让我们再回顾一下这个报错,说是 布尔序列的索引和索引对象的索引不匹配 。
第一步
首先,我们会有个疑问,这句话说的 布尔序列 哪里来的?
思考再三,我恍然大悟,应该是
df['en'] == kw
这句话来的。这句话会返回一个 和 df
行数一样,值都是 bool
的 Series
,然后 pandas
会取出这个 布尔序列 中值为 True
的多行数据。
第二步
然后,我们要知道它说的 和索引对象的索引不匹配 是什么意思。
索引对象 就是我们这个小例子中的 df
。也就是说,我们查找数据是查找的 df
中的数据,df
就是我们的 索引对象,既然是要从这里找数据,那我们就必须保证 df
的 索引 与上一步得到的 布尔序列 的索引一模一样(因为是根据值为 True
的数据对应的 索引 取数据),否则,我们是根本取不到对应索引的数据的。
如果说我们现在有个 DataFrame
是
name
0 张三
1 李四
3 王五
而我们要取数据的布尔序列是
0 False
2 True
3 False
那我们这时候就 根本不能取到数据,而且会报上述错误,因为 DataFrame
中就没有 索引为 2
的数据,你想让它给你造一个出来,那也不现实是不是?
解决
既然我们已经找到了问题所在,下面就是要解决这个问题了。
我的问题解决方案
先看一下我的问题,我的代码报错是因为:
开启多线程后,由于没有设置 锁
,多个线程同时访问全局变量 df
,导致其中一个线程 get
要进行 取数据
操作时,另一个线程 put
刚好在 get
线程执行完获得 布尔序列
语句与执行 查找数据
命令之间的时间对 df
进行了修改,导致 索引发生变化
,因为写操作只有 增加
,所以就是 get
线程获得 布尔序列
时 df
的行数小于 get
线程执行 查找操作
时 df
的行数,导致报错 。
可能我说的不是那么清晰,那就看一下下边的 时序图 。
那我的解决办法就是:执行 查找操作 时 上锁
,同一时间只能进行 读操作 或 写操作。
所以修改代码为:
lock.acquire()
check_exists = df['en'] == kw
lock.release()
成功解决问题!!!
通用解决方案
有可能你的出错原因和我的不太一样,我的解决方案可能不太适用,所以我在这里给出一个通用的解决方案。
使用函数 reset_index
或者 reindex()
。
-
reset_index()
,使用方法见 文档。
一般来说,我们只需要看参数drop
和inplace
即可drop
,是否删除原索引,如果要删除的话就设置为True
inplace
, 是否覆盖原DataFrame
,如果要覆盖的话就设置为True
-
reindex()
,使用方法见 文档。
keywords for axes
,指定作为索引的轴。method
,指定填补空白的方法,默认不填充空白。copy
,是否复制为新对象。level
,多重索引时,指定要更改索引的层级。fill_value
,填补缺失值的值,默认为Nan
。limit
,向前或向后填充的最大连续元素的个数。tolerance
,不精确匹配的原始标签和新标签之间的最大距离,要满足方程 a b s ( i n d e x [ i n d e x e r ] − t a r g e t ) < = t o l e r a n c e abs(index[indexer] - target) <= tolerance abs(index[indexer]−target)<=tolerance。
可以自行尝试。
结尾
有想要一起学习 python
的小伙伴可以 私信我
进群哦。
以上就是我要分享的内容,因为学识尚浅,会有不足,还请各位大佬指正。
有什么问题也可在评论区留言。
更多推荐
所有评论(0)