diff --git a/doc/source/whatsnew/v1.5.1.rst b/doc/source/whatsnew/v1.5.1.rst index c1bc203ec2fad..51a0d6ed0ff9f 100644 --- a/doc/source/whatsnew/v1.5.1.rst +++ b/doc/source/whatsnew/v1.5.1.rst @@ -28,6 +28,7 @@ Fixed regressions Bug fixes ~~~~~~~~~ - Bug in :meth:`DataFrame.to_hdf` raising ``AssertionError`` with boolean index (:issue:`48667`) +- Bug in :func:`assert_index_equal` for extension arrays with non matching ``NA`` raising ``ValueError`` (:issue:`48608`) - Bug in :meth:`DataFrame.pivot_table` raising unexpected ``FutureWarning`` when setting datetime column as index (:issue:`48683`) - diff --git a/pandas/_libs/testing.pyx b/pandas/_libs/testing.pyx index e710a6fb6b24e..679cde9932a7a 100644 --- a/pandas/_libs/testing.pyx +++ b/pandas/_libs/testing.pyx @@ -182,6 +182,10 @@ cpdef assert_almost_equal(a, b, # nan / None comparison return True + if isna(a) and not isna(b) or not isna(a) and isna(b): + # boolean value of pd.NA is ambigous + raise AssertionError(f"{a} != {b}") + if a == b: # object comparison return True diff --git a/pandas/_testing/asserters.py b/pandas/_testing/asserters.py index db850ffdc4e1f..9b8e171413b57 100644 --- a/pandas/_testing/asserters.py +++ b/pandas/_testing/asserters.py @@ -398,6 +398,9 @@ def _get_ilevel_values(index, level): if not left.equals(right): mismatch = left._values != right._values + if is_extension_array_dtype(mismatch): + mismatch = cast("ExtensionArray", mismatch).fillna(True) + diff = np.sum(mismatch.astype(int)) * 100.0 / len(left) msg = f"{obj} values are different ({np.round(diff, 5)} %)" raise_assert_detail(obj, msg, left, right) diff --git a/pandas/tests/util/test_assert_index_equal.py b/pandas/tests/util/test_assert_index_equal.py index 0b2c2e12a2d2a..71799c73f35c6 100644 --- a/pandas/tests/util/test_assert_index_equal.py +++ b/pandas/tests/util/test_assert_index_equal.py @@ -280,3 +280,15 @@ def test_assert_index_equal_object_ints_order_false(): idx1 = Index([1, 3], dtype="object") idx2 = Index([3, 1], dtype="object") tm.assert_index_equal(idx1, idx2, check_order=False) + + +@pytest.mark.parametrize("check_categorical", [True, False]) +@pytest.mark.parametrize("check_names", [True, False]) +def test_assert_ea_index_equal_non_matching_na(check_names, check_categorical): + # GH#48608 + idx1 = Index([1, 2], dtype="Int64") + idx2 = Index([1, NA], dtype="Int64") + with pytest.raises(AssertionError, match="50.0 %"): + tm.assert_index_equal( + idx1, idx2, check_names=check_names, check_categorical=check_categorical + )