Pandas 报错 Unalignable boolean Series provided as indexer 的解决方法

Pandas 报错 Unalignable boolean Series provided as indexer 的解决方法

前言

最近本菜鸡在 批量处理 数据的时候出现了问题,场景是:批量获得数据,判断是否在指定 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 行数一样,值都是 boolSeries ,然后 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 的行数,导致报错
可能我说的不是那么清晰,那就看一下下边的 时序图

get df put series = df['en'] == kw, (series.index=(1,...,n)) df.index=(1,...,n) df.loc[df.shape[0]+1]=data df.index=(1,...,n+1) df[series], (series.index=(1,...,n)) df.index=(1,...,n+1) get df put

那我的解决办法就是:执行 查找操作上锁,同一时间只能进行 读操作写操作
所以修改代码为:

lock.acquire()
check_exists = df['en'] == kw
lock.release()

成功解决问题!!!

通用解决方案

有可能你的出错原因和我的不太一样,我的解决方案可能不太适用,所以我在这里给出一个通用的解决方案。

使用函数 reset_index 或者 reindex()

  • reset_index(),使用方法见 文档

    在这里插入图片描述
    一般来说,我们只需要看参数 dropinplace 即可

    • 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 的小伙伴可以 私信我 进群哦。

以上就是我要分享的内容,因为学识尚浅,会有不足,还请各位大佬指正。
有什么问题也可在评论区留言。
在这里插入图片描述

  • 17
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
这个错误通常是由于索引不匹配引起的。具体来说,通常是在使用布尔索引时出现了这个问题,因为布尔索引要求索引的长度和布尔值的长度必须相等,并且要求两者的索引必须匹配。如果两者的索引不匹配,就会触发 `IndexingError`。 例如,假设你有两个 DataFrame,分别是 `df1` 和 `df2`,并且它们的索引不匹配。你想要使用 `df1` 中的一个布尔 Series 来选择 `df2` 中的一些行,你可以这样做: ``` import pandas as pd df1 = pd.DataFrame({'A': [True, False, True], 'B': [1, 2, 3]}) df2 = pd.DataFrame({'C': [4, 5, 6], 'D': [True, False, True], 'E': ['a', 'b', 'c']}) mask = df1['A'] result = df2[mask] print(result) ``` 输出: ``` --------------------------------------------------------------------------- IndexingError Traceback (most recent call last) <ipython-input-4-3e0a7e8e9d7e> in <module>() 5 df2 = pd.DataFrame({'C': [4, 5, 6], 'D': [True, False, True], 'E': ['a', 'b', 'c']}) 6 mask = df1['A'] ----> 7 result = df2[mask] 8 print(result) ... IndexingError: Unalignable boolean Series provided as indexer (index of the boolean Series and of the indexed object do not match). ``` 你可以看到,这个例子中出现了 `IndexingError`,因为 `df1` 和 `df2` 的索引不匹配。在这种情况下,你需要确保两个 DataFrame 的索引一致,或者使用 `reset_index()` 方法来将其中一个 DataFrame 的索引重置为默认的整数索引。例如,你可以这样修改上面的代码: ``` import pandas as pd df1 = pd.DataFrame({'A': [True, False, True], 'B': [1, 2, 3]}, index=['a', 'b', 'c']) df2 = pd.DataFrame({'C': [4, 5, 6], 'D': [True, False, True], 'E': ['a', 'b', 'c']}) mask = df1['A'] result = df2[mask.reset_index(drop=True)] print(result) ``` 输出: ``` C D E 0 4 True a 2 6 True c ``` 在这个例子中,我将 `df1` 的索引修改为了 `['a', 'b', 'c']`,并使用 `reset_index()` 方法将 `mask` 的索引重置为默认的整数索引。这样,就可以使用 `mask` 来选择 `df2` 中的行了。注意,由于 `mask` 的索引已经重置了,所以在使用布尔索引时不需要考虑索引不匹配的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值