diff --git a/doc/source/v0.15.0.txt b/doc/source/v0.15.0.txt index 92fd228ccd10e..2776f6f9fcb35 100644 --- a/doc/source/v0.15.0.txt +++ b/doc/source/v0.15.0.txt @@ -1006,3 +1006,4 @@ Bug Fixes - Bug in ``DataFrame.dropna`` that interpreted non-existent columns in the subset argument as the 'last column' (:issue:`8303`) - Bug in Index.intersection on non-monotonic non-unique indexes (:issue:`8362`). - Bug in masked series assignment where mismatching types would break alignment (:issue:`8387`) +- Bug in NDFrame.equals gives false negatives with dtype=object (:issue:`8437`) diff --git a/pandas/core/internals.py b/pandas/core/internals.py index 354ccd2c94583..542dc69aa35f4 100644 --- a/pandas/core/internals.py +++ b/pandas/core/internals.py @@ -13,7 +13,7 @@ ABCSparseSeries, _infer_dtype_from_scalar, _is_null_datelike_scalar, is_timedelta64_dtype, is_datetime64_dtype, - _possibly_infer_to_datetimelike) + _possibly_infer_to_datetimelike, array_equivalent) from pandas.core.index import Index, MultiIndex, _ensure_index from pandas.core.indexing import (_maybe_convert_indices, _length_of_indexer) from pandas.core.categorical import Categorical, _maybe_to_categorical, _is_categorical @@ -1057,7 +1057,7 @@ def func(c, v, o): def equals(self, other): if self.dtype != other.dtype or self.shape != other.shape: return False - return np.array_equal(self.values, other.values) + return array_equivalent(self.values, other.values) class NonConsolidatableMixIn(object): diff --git a/pandas/tests/test_generic.py b/pandas/tests/test_generic.py index 0734da1ab09aa..fd457c93f92fa 100644 --- a/pandas/tests/test_generic.py +++ b/pandas/tests/test_generic.py @@ -1304,6 +1304,21 @@ def test_equals(self): df2 = df1.set_index(['floats'], append=True) self.assertTrue(df3.equals(df2)) + # GH 8437 + a = pd.Series([False, np.nan]) + b = pd.Series([False, np.nan]) + c = pd.Series(index=range(2)) + d = pd.Series(index=range(2)) + e = pd.Series(index=range(2)) + f = pd.Series(index=range(2)) + c[:-1] = d[:-1] = e[0] = f[0] = False + self.assertTrue(a.equals(a)) + self.assertTrue(a.equals(b)) + self.assertTrue(a.equals(c)) + self.assertTrue(a.equals(d)) + self.assertFalse(a.equals(e)) + self.assertTrue(e.equals(f)) + def test_describe_raises(self): with tm.assertRaises(NotImplementedError): tm.makePanel().describe()