为什么pandas'=='与'.eq()'不同

piR*_*red 10 python pandas

考虑这个系列 s

s = pd.Series([(1, 2), (3, 4), (5, 6)])
Run Code Online (Sandbox Code Playgroud)

这是预期的

s == (3, 4)

0    False
1     True
2    False
dtype: bool
Run Code Online (Sandbox Code Playgroud)

这不是

s.eq((3, 4))
Run Code Online (Sandbox Code Playgroud)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)

ValueError: Lengths must be equal
Run Code Online (Sandbox Code Playgroud)

我假设他们是一样的.他们之间有什么区别?


什么是文件说?

相当于series == other,但支持在其中一个输入中用fill_value替换缺失数据.

这似乎意味着他们应该工作相同,因此混乱.

MSe*_*ert 5

实际上,您遇到的是一个特例,可以轻松比较pandas.Seriesnumpy.ndarray与常规python构造进行比较。源代码为:

def flex_wrapper(self, other, level=None, fill_value=None, axis=0):
    # validate axis
    if axis is not None:
        self._get_axis_number(axis)
    if isinstance(other, ABCSeries):
        return self._binop(other, op, level=level, fill_value=fill_value)
    elif isinstance(other, (np.ndarray, list, tuple)):
        if len(other) != len(self):
            # ---------------------------------------
            # you never reach the `==` path because you get into this.
            # ---------------------------------------
            raise ValueError('Lengths must be equal')  
        return self._binop(self._constructor(other, self.index), op,
                           level=level, fill_value=fill_value)
    else:
        if fill_value is not None:
            self = self.fillna(fill_value)

        return self._constructor(op(self, other),
                                 self.index).__finalize__(self)
Run Code Online (Sandbox Code Playgroud)

ValueError之所以.eq这么打,是因为pandas假设您希望将值转换为numpy.ndarrayor pandas.Series如果给它一个数组,列表或元组),而不是实际将其与进行比较tuple。例如,如果您有:

s = pd.Series([1,2,3])
s.eq([1,2,3])
Run Code Online (Sandbox Code Playgroud)

您不希望它将每个元素与进行比较[1,2,3]

问题在于,object阵列(和一样dtype=uint)经常会滑过裂缝或被故意忽略。if self.dtype != 'object'该方法中的一个简单分支可以解决此问题。但是,也许开发人员有充分的理由使这种情况有所不同。我建议通过在他们的错误跟踪器上发布来要求澄清。


您没有问过如何使其正常工作,但是为了完整起见,我将提供一种可能性(根据源代码,似乎您需要将其包装为pandas.Series自己):

>>> s.eq(pd.Series([(1, 2)]))
0     True
1    False
2    False
dtype: bool
Run Code Online (Sandbox Code Playgroud)