【问题标题】:Bitwise comparison of "slightly" different DataFrames yield conflicting results“稍微”不同的 DataFrame 的按位比较会产生相互冲突的结果
【发布时间】:2022-07-19 05:17:50
【问题描述】:

在研究涉及按位 AND 运算符的主题时,我偶然发现了以下事件。

访问 Pandas DataFrame 的 Series 并执行相同的条件检查,返回的结果不同。

  1. 第 95 行和第 96 行的幕后发生了什么?
  2. 为什么两个数据帧的结果不同?
    In [91]: df = pd.DataFrame({\"h\": [5300, 5420, 5490], \"l\": [5150, 5270, 5270]})
    
    In [92]: df
    Out[92]: 
          h     l
    0  5300  5150
    1  5420  5270
    2  5490  5270
    
    In [93]: df2 = pd.DataFrame({\"h\": [5300.1, 5420.1, 5490.1], \"l\": [5150.1, 5270.1, 5270.1]})
    
    In [94]: df2
    Out[94]: 
            h       l
    0  5300.1  5150.1
    1  5420.1  5270.1
    2  5490.1  5270.1
    
    In [95]: df[\"h\"].notna() & df[\"l\"]
    Out[95]: 
    0    False
    1    False
    2    False
    dtype: bool
    
    In [96]: df2[\"h\"].notna() & df2[\"l\"]
    Out[96]: 
    0    True
    1    True
    2    True
    dtype: bool
    
    In [97]: 
    

    标签: python pandas dataframe bitwise-operators


    【解决方案1】:

    您遇到了一些奇怪的隐式转换。我相信你的意思是:

    df["h"].notna() & df["l"].notna()
    

    也许

    df["h"].notna() & df["l"].astype(bool)
    

    在原来的,

    df["h"].notna() & df["l"]
    

    您已请求对两个系列进行按位运算,其中第一个是 dtyped 为布尔值,第二个是整数(在 df 中)或浮点数(在 df2 中)。

    在第一种情况下,布尔值可以向上转换为 int。似乎发生的事情是布尔值 True 向上转换为整数 1(二进制 0000000001),与整数 5150、5270 和 5270 进行按位与运算(给出 0,因为所有这些都是偶数)。例如。如果你设置

    df.loc[2, 'l'] = 5271
    

    您将看到最终值更改为 True。

    在 df2 的情况下,float 和 bool 不能在逻辑上与在一起。看来,这里的 Pandas 可能会隐式地将浮点数组的 dtype 转换为 bool。 numpy 本身不会这样做:

    In [79]: np.float64([.1, .2]) & np.array([True, True])
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-79-2c2e50f0bf99> in <module>
    ----> 1 np.float64([.1, .2]) & np.array([True, True])
    
    TypeError: ufunc 'bitwise_and' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
    

    但熊猫似乎允许这样做:

    In [88]: pd.Series([True, True, True]) & pd.Series([0, .1, .2])
    Out[88]:
    0    False
    1     True
    2     True
    dtype: bool
    

    通过显式使用 astype bool 可以在 numpy 中获得相同的结果:

    In [92]: np.array([True, True, True]) & np.float64([0, .1, .2]).astype(bool)
    Out[92]: array([False,  True,  True])
    

    【讨论】:

      【解决方案2】:

      浮点数的按位比较没有意义,并在 Python 级别引发错误:

      >>> float(10) & True
      ...
      TypeError: unsupported operand type(s) for &: 'float' and 'bool'
      
      >>> int(10) & True
      0
      

      【讨论】:

        【解决方案3】:

        Pandas notna 函数仅对浮点列有意义。整数列没有 NaN 值,因此它返回 False 以提醒您这一点。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-07-18
          • 2020-08-31
          • 1970-01-01
          • 1970-01-01
          • 2020-07-04
          • 2015-01-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多