【问题标题】:Pandas boolean DataFrame selection ambiguityPandas boolean DataFrame 选择歧义
【发布时间】:2014-11-12 02:53:49
【问题描述】:

编辑:表格中的固定值。

假设我有一个 pandas 数据框 df:

>>>df
                  a         b         c
        0  0.016367  0.289944 -0.891527
        1  1.130206  0.899758 -0.276587
        2  1.390528 -1.472802  0.128979
        3  0.023598 -0.931329  0.158143
        4  1.401183 -0.162357 -0.959156
        5 -0.127765  1.142039 -0.734434

所以现在我尝试做一些布尔索引:

>>>df[df > 0.5]
          a         b         c
0       NaN       NaN        Nan
1  1.130206  0.899758        NaN
2  1.390528       NaN        NaN
3       NaN       NaN        NaN
4  1.401183       NaN        NaN
5       NaN  1.142039        NaN

>>>df[df < 0]
          a         b         c
0       NaN       NaN -0.891527
1       NaN       NaN -0.276587
2       NaN -1.472802       NaN
3       NaN -0.931329       NaN
4       NaN -0.162357 -0.959156
5 -0.127765       NaN -0.734434

所以现在我尝试对条件进行逻辑或作为索引条件:

>>>df[df > 0.5 or df < 0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\Ben\Anaconda\lib\site-packages\pandas\core\generic.py", line 692, in __nonzero__
.format(self.__class__.__name__))
ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any()    or a.all().

我对此进行了一些研究,这是一个基本功能,numpy 的开发人员决定某些条件在任何或所有情况下都可能是模棱两可的。我不明白为什么检查值是否 > 0.5 有效并检查其 0.5 或

【问题讨论】:

    标签: python numpy pandas


    【解决方案1】:

    自定义类型无法覆盖 Python 中 andor 的行为。也就是说,Numpy 不可能说它希望 [0, 1, 1] and [1, 1, 0] 成为 [0, 1, 0]。这是因为and 操作短路(参见the documentation);本质上,andor 的短路行为意味着这些操作必须作为两个参数的两个独立真值工作;他们不能以某种方式组合他们的两个操作数,同时利用两个操作数中的数据(例如,按组件比较元素,这对于 Numpy 来说很自然)。

    解决方案是使用按位运算符&amp;|。但是,您必须小心这一点,因为优先级不是您所期望的。

    【讨论】:

    • 有趣的是,我不知道 numpy 中的这种行为。当您说优先级并不总是您所期望的时,您的意思是什么副作用?有没有更惯用的方法来根据复合布尔表达式过滤 numpy/pandas 对象?
    • @user3299166:按位运算符的优先级高于比较运算符,因此例如 1 &lt; 2 &amp; 0 &lt; 1 为假(它被解释为 (1 &lt; (2 &amp; 0) &lt; 1)。最好的办法是使用按位运算符,但是将它们的操作数括起来以避免意外,例如,df[(df.A &lt; 5) &amp; (df.B &gt; 0)]
    【解决方案2】:

    由于逻辑运算符在 python 中不可覆盖,numpy 和 pandas 会覆盖位运算符。

    这意味着您需要使用按位或运算符:

    df[(df > 0.5) | (df < 0)]
    

    【讨论】:

      【解决方案3】:

      您需要使用按位或并将条件放在括号中:

      df[(df > 0.5) | (df < 0)]
      

      原因是当数组中的某些值可能满足条件时比较数组是不明确的,这就是它变得不明确的原因。

      如果您调用属性 any,那么它的计算结果为 True。

      由于运算符优先级,括号是必需的。

      例子:

      In [23]:
      
      df = pd.DataFrame(randn(5,5))
      df
      Out[23]:
                0         1         2         3         4
      0  0.320165  0.123677 -0.202609  1.225668  0.327576
      1 -0.620356  0.126270  1.191855  0.903879  0.214802
      2 -0.974635  1.712151  1.178358  0.224962 -0.921045
      3 -1.337430 -1.225469  1.150564 -1.618739 -1.297221
      4 -0.093164 -0.928846  1.035407  1.766096  1.456888
      In [24]:
      
      df[(df > 0.5) | (df < 0)]
      Out[24]:
                0         1         2         3         4
      0       NaN       NaN -0.202609  1.225668       NaN
      1 -0.620356       NaN  1.191855  0.903879       NaN
      2 -0.974635  1.712151  1.178358       NaN -0.921045
      3 -1.337430 -1.225469  1.150564 -1.618739 -1.297221
      4 -0.093164 -0.928846  1.035407  1.766096  1.456888
      

      【讨论】:

      • 有道理,有没有办法使用 any() 执行所需的过滤?
      • 老实说,这没什么用,基本上你仍然必须使用按位运算符,如果你说df[df.any() &gt; 0.5],如果单个元素满足条件,它将返回整个 df这不会有太大用处
      猜你喜欢
      • 2014-11-04
      • 1970-01-01
      • 2016-07-16
      • 1970-01-01
      • 2021-05-07
      • 2019-05-24
      相关资源
      最近更新 更多