diff --git a/pandas/core/common.py b/pandas/core/common.py index da512dc56eaef..1e3d789ce206b 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -411,12 +411,13 @@ def array_equivalent(left, right, strict_nan=False): if left.shape != right.shape: return False # Object arrays can contain None, NaN and NaT. - if issubclass(left.dtype.type, np.object_): + if issubclass(left.dtype.type, np.object_) or issubclass(right.dtype.type, np.object_): if not strict_nan: # pd.isnull considers NaN and None to be equivalent. - return lib.array_equivalent_object(left.ravel(), right.ravel()) - + return lib.array_equivalent_object(_ensure_object(left.ravel()), + _ensure_object(right.ravel())) + for left_value, right_value in zip(left, right): if left_value is tslib.NaT and right_value is not tslib.NaT: return False diff --git a/pandas/lib.pyx b/pandas/lib.pyx index a845b9c90865b..88c458ce95226 100644 --- a/pandas/lib.pyx +++ b/pandas/lib.pyx @@ -330,26 +330,6 @@ def list_to_object_array(list obj): return arr -@cython.wraparound(False) -@cython.boundscheck(False) -def array_equivalent_object(ndarray left, ndarray right): - cdef Py_ssize_t i, n - cdef object lobj, robj - - n = len(left) - for i from 0 <= i < n: - lobj = left[i] - robj = right[i] - - # we are either not equal or both nan - # I think None == None will be true here - if lobj != robj: - if checknull(lobj) and checknull(robj): - continue - return False - return True - - @cython.wraparound(False) @cython.boundscheck(False) def fast_unique(ndarray[object] values): @@ -692,6 +672,31 @@ def scalar_compare(ndarray[object] values, object val, object op): return result.view(bool) +@cython.wraparound(False) +@cython.boundscheck(False) +def array_equivalent_object(ndarray[object] left, ndarray[object] right): + """ perform an element by element comparion on 1-d object arrays + taking into account nan positions """ + cdef Py_ssize_t i, n + cdef object x, y + + n = len(left) + for i from 0 <= i < n: + x = left[i] + y = right[i] + + # we are either not equal or both nan + # I think None == None will be true here + if cpython.PyObject_RichCompareBool(x, y, cpython.Py_EQ): + continue + elif _checknull(x) and _checknull(y): + continue + else: + return False + + return True + + @cython.wraparound(False) @cython.boundscheck(False) def vec_compare(ndarray[object] left, ndarray[object] right, object op):