2016-12-31 4 views
7

Рассмотрим ряд sПочему панд == 'отличается от '.EQ()'

s = pd.Series([(1, 2), (3, 4), (5, 6)]) 

Это, как ожидается,

s == (3, 4) 

0 False 
1  True 
2 False 
dtype: bool 

Это не

s.eq((3, 4)) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 

ValueError: Lengths must be equal 

Я был в предположении, что они были такими же. В чем разница между ними?


Что делает documentation сказать?

Эквивалент серии == другой, но с поддержкой подменить fill_value недостающих данных в одном из входов.

Это, по-видимому, означает, что они должны работать одинаково, отсюда и путаница.

+0

@piRSquared: теперь лучше, что вы добавили некоторые доказательства исследовательской работы в сообщение! Сначала вы только что сказали, что предположили вещь X и оставили ее на этом –

ответ

3

То, что вы встретите, на самом деле является особым случаем, который упрощает сравнение pandas.Series или numpy.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) 

Вы ударять ValueError, потому что панды предполагает для .eq, что вы хотите, значение преобразуется в numpy.ndarray или pandas.Series (, если вы даете ему массив, список или кортеж) вместо фактически сравнивая его с tuple. Например, если у вас есть:

s = pd.Series([1,2,3]) 
s.eq([1,2,3]) 

вы не хотите, чтобы сравнить каждый элемент [1,2,3].

Проблема в том, что массивы object (как и в случае с dtype=uint) часто проскальзывают через трещины или пренебрегают нарочно. Простая ветка if self.dtype != 'object' внутри этого метода может решить эту проблему. Но, возможно, у разработчиков были веские причины, чтобы сделать этот случай другим. Я бы посоветовал попросить разъяснений, разместив их на своем bug tracker.


Вы не спросили, как вы можете заставить его работать правильно, но для Комплектность я буду включать одну возможность (в соответствии с исходным кодом, кажется, скорее всего, вам нужно обернуть его как pandas.Series себя):

>>> s.eq(pd.Series([(1, 2)])) 
0  True 
1 False 
2 False 
dtype: bool 
0

== - это элементное сравнение, которое дает вектор значений истинности, тогда как .eq - это «эти два итерабельности равны», для которых требуется такая же длина. Айхан указывает на одно исключение: когда вы сравниваете векторный тип панды с использованием .eq(scalar value), скалярное значение просто передается на вектор такого же размера для сравнения.

+1

. Она транслируется, когда вы используете скаляр: 's.eq (3)' например. – ayhan

Смежные вопросы