123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533 |
- import numpy as np
- import pytest
- from pandas import (
- DataFrame,
- Index,
- Series,
- Timestamp,
- )
- import pandas._testing as tm
- def _assert_almost_equal_both(a, b, **kwargs):
- """
- Check that two objects are approximately equal.
- This check is performed commutatively.
- Parameters
- ----------
- a : object
- The first object to compare.
- b : object
- The second object to compare.
- **kwargs
- The arguments passed to `tm.assert_almost_equal`.
- """
- tm.assert_almost_equal(a, b, **kwargs)
- tm.assert_almost_equal(b, a, **kwargs)
- def _assert_not_almost_equal(a, b, **kwargs):
- """
- Check that two objects are not approximately equal.
- Parameters
- ----------
- a : object
- The first object to compare.
- b : object
- The second object to compare.
- **kwargs
- The arguments passed to `tm.assert_almost_equal`.
- """
- try:
- tm.assert_almost_equal(a, b, **kwargs)
- msg = f"{a} and {b} were approximately equal when they shouldn't have been"
- pytest.fail(msg=msg)
- except AssertionError:
- pass
- def _assert_not_almost_equal_both(a, b, **kwargs):
- """
- Check that two objects are not approximately equal.
- This check is performed commutatively.
- Parameters
- ----------
- a : object
- The first object to compare.
- b : object
- The second object to compare.
- **kwargs
- The arguments passed to `tm.assert_almost_equal`.
- """
- _assert_not_almost_equal(a, b, **kwargs)
- _assert_not_almost_equal(b, a, **kwargs)
- @pytest.mark.parametrize(
- "a,b",
- [
- (1.1, 1.1),
- (1.1, 1.100001),
- (np.int16(1), 1.000001),
- (np.float64(1.1), 1.1),
- (np.uint32(5), 5),
- ],
- )
- def test_assert_almost_equal_numbers(a, b):
- _assert_almost_equal_both(a, b)
- @pytest.mark.parametrize(
- "a,b",
- [
- (1.1, 1),
- (1.1, True),
- (1, 2),
- (1.0001, np.int16(1)),
- # The following two examples are not "almost equal" due to tol.
- (0.1, 0.1001),
- (0.0011, 0.0012),
- ],
- )
- def test_assert_not_almost_equal_numbers(a, b):
- _assert_not_almost_equal_both(a, b)
- @pytest.mark.parametrize(
- "a,b",
- [
- (1.1, 1.1),
- (1.1, 1.100001),
- (1.1, 1.1001),
- (0.000001, 0.000005),
- (1000.0, 1000.0005),
- # Testing this example, as per #13357
- (0.000011, 0.000012),
- ],
- )
- def test_assert_almost_equal_numbers_atol(a, b):
- # Equivalent to the deprecated check_less_precise=True, enforced in 2.0
- _assert_almost_equal_both(a, b, rtol=0.5e-3, atol=0.5e-3)
- @pytest.mark.parametrize("a,b", [(1.1, 1.11), (0.1, 0.101), (0.000011, 0.001012)])
- def test_assert_not_almost_equal_numbers_atol(a, b):
- _assert_not_almost_equal_both(a, b, atol=1e-3)
- @pytest.mark.parametrize(
- "a,b",
- [
- (1.1, 1.1),
- (1.1, 1.100001),
- (1.1, 1.1001),
- (1000.0, 1000.0005),
- (1.1, 1.11),
- (0.1, 0.101),
- ],
- )
- def test_assert_almost_equal_numbers_rtol(a, b):
- _assert_almost_equal_both(a, b, rtol=0.05)
- @pytest.mark.parametrize("a,b", [(0.000011, 0.000012), (0.000001, 0.000005)])
- def test_assert_not_almost_equal_numbers_rtol(a, b):
- _assert_not_almost_equal_both(a, b, rtol=0.05)
- @pytest.mark.parametrize(
- "a,b,rtol",
- [
- (1.00001, 1.00005, 0.001),
- (-0.908356 + 0.2j, -0.908358 + 0.2j, 1e-3),
- (0.1 + 1.009j, 0.1 + 1.006j, 0.1),
- (0.1001 + 2.0j, 0.1 + 2.001j, 0.01),
- ],
- )
- def test_assert_almost_equal_complex_numbers(a, b, rtol):
- _assert_almost_equal_both(a, b, rtol=rtol)
- _assert_almost_equal_both(np.complex64(a), np.complex64(b), rtol=rtol)
- _assert_almost_equal_both(np.complex128(a), np.complex128(b), rtol=rtol)
- @pytest.mark.parametrize(
- "a,b,rtol",
- [
- (0.58310768, 0.58330768, 1e-7),
- (-0.908 + 0.2j, -0.978 + 0.2j, 0.001),
- (0.1 + 1j, 0.1 + 2j, 0.01),
- (-0.132 + 1.001j, -0.132 + 1.005j, 1e-5),
- (0.58310768j, 0.58330768j, 1e-9),
- ],
- )
- def test_assert_not_almost_equal_complex_numbers(a, b, rtol):
- _assert_not_almost_equal_both(a, b, rtol=rtol)
- _assert_not_almost_equal_both(np.complex64(a), np.complex64(b), rtol=rtol)
- _assert_not_almost_equal_both(np.complex128(a), np.complex128(b), rtol=rtol)
- @pytest.mark.parametrize("a,b", [(0, 0), (0, 0.0), (0, np.float64(0)), (0.00000001, 0)])
- def test_assert_almost_equal_numbers_with_zeros(a, b):
- _assert_almost_equal_both(a, b)
- @pytest.mark.parametrize("a,b", [(0.001, 0), (1, 0)])
- def test_assert_not_almost_equal_numbers_with_zeros(a, b):
- _assert_not_almost_equal_both(a, b)
- @pytest.mark.parametrize("a,b", [(1, "abc"), (1, [1]), (1, object())])
- def test_assert_not_almost_equal_numbers_with_mixed(a, b):
- _assert_not_almost_equal_both(a, b)
- @pytest.mark.parametrize(
- "left_dtype", ["M8[ns]", "m8[ns]", "float64", "int64", "object"]
- )
- @pytest.mark.parametrize(
- "right_dtype", ["M8[ns]", "m8[ns]", "float64", "int64", "object"]
- )
- def test_assert_almost_equal_edge_case_ndarrays(left_dtype, right_dtype):
- # Empty compare.
- _assert_almost_equal_both(
- np.array([], dtype=left_dtype),
- np.array([], dtype=right_dtype),
- check_dtype=False,
- )
- def test_assert_almost_equal_dicts():
- _assert_almost_equal_both({"a": 1, "b": 2}, {"a": 1, "b": 2})
- @pytest.mark.parametrize(
- "a,b",
- [
- ({"a": 1, "b": 2}, {"a": 1, "b": 3}),
- ({"a": 1, "b": 2}, {"a": 1, "b": 2, "c": 3}),
- ({"a": 1}, 1),
- ({"a": 1}, "abc"),
- ({"a": 1}, [1]),
- ],
- )
- def test_assert_not_almost_equal_dicts(a, b):
- _assert_not_almost_equal_both(a, b)
- @pytest.mark.parametrize("val", [1, 2])
- def test_assert_almost_equal_dict_like_object(val):
- dict_val = 1
- real_dict = {"a": val}
- class DictLikeObj:
- def keys(self):
- return ("a",)
- def __getitem__(self, item):
- if item == "a":
- return dict_val
- func = (
- _assert_almost_equal_both if val == dict_val else _assert_not_almost_equal_both
- )
- func(real_dict, DictLikeObj(), check_dtype=False)
- def test_assert_almost_equal_strings():
- _assert_almost_equal_both("abc", "abc")
- @pytest.mark.parametrize(
- "a,b", [("abc", "abcd"), ("abc", "abd"), ("abc", 1), ("abc", [1])]
- )
- def test_assert_not_almost_equal_strings(a, b):
- _assert_not_almost_equal_both(a, b)
- @pytest.mark.parametrize(
- "a,b", [([1, 2, 3], [1, 2, 3]), (np.array([1, 2, 3]), np.array([1, 2, 3]))]
- )
- def test_assert_almost_equal_iterables(a, b):
- _assert_almost_equal_both(a, b)
- @pytest.mark.parametrize(
- "a,b",
- [
- # Class is different.
- (np.array([1, 2, 3]), [1, 2, 3]),
- # Dtype is different.
- (np.array([1, 2, 3]), np.array([1.0, 2.0, 3.0])),
- # Can't compare generators.
- (iter([1, 2, 3]), [1, 2, 3]),
- ([1, 2, 3], [1, 2, 4]),
- ([1, 2, 3], [1, 2, 3, 4]),
- ([1, 2, 3], 1),
- ],
- )
- def test_assert_not_almost_equal_iterables(a, b):
- _assert_not_almost_equal(a, b)
- def test_assert_almost_equal_null():
- _assert_almost_equal_both(None, None)
- @pytest.mark.parametrize("a,b", [(None, np.NaN), (None, 0), (np.NaN, 0)])
- def test_assert_not_almost_equal_null(a, b):
- _assert_not_almost_equal(a, b)
- @pytest.mark.parametrize(
- "a,b",
- [
- (np.inf, np.inf),
- (np.inf, float("inf")),
- (np.array([np.inf, np.nan, -np.inf]), np.array([np.inf, np.nan, -np.inf])),
- (
- np.array([np.inf, None, -np.inf], dtype=np.object_),
- np.array([np.inf, np.nan, -np.inf], dtype=np.object_),
- ),
- ],
- )
- def test_assert_almost_equal_inf(a, b):
- _assert_almost_equal_both(a, b)
- def test_assert_not_almost_equal_inf():
- _assert_not_almost_equal_both(np.inf, 0)
- @pytest.mark.parametrize(
- "a,b",
- [
- (Index([1.0, 1.1]), Index([1.0, 1.100001])),
- (Series([1.0, 1.1]), Series([1.0, 1.100001])),
- (np.array([1.1, 2.000001]), np.array([1.1, 2.0])),
- (DataFrame({"a": [1.0, 1.1]}), DataFrame({"a": [1.0, 1.100001]})),
- ],
- )
- def test_assert_almost_equal_pandas(a, b):
- _assert_almost_equal_both(a, b)
- def test_assert_almost_equal_object():
- a = [Timestamp("2011-01-01"), Timestamp("2011-01-01")]
- b = [Timestamp("2011-01-01"), Timestamp("2011-01-01")]
- _assert_almost_equal_both(a, b)
- def test_assert_almost_equal_value_mismatch():
- msg = "expected 2\\.00000 but got 1\\.00000, with rtol=1e-05, atol=1e-08"
- with pytest.raises(AssertionError, match=msg):
- tm.assert_almost_equal(1, 2)
- @pytest.mark.parametrize(
- "a,b,klass1,klass2",
- [(np.array([1]), 1, "ndarray", "int"), (1, np.array([1]), "int", "ndarray")],
- )
- def test_assert_almost_equal_class_mismatch(a, b, klass1, klass2):
- msg = f"""numpy array are different
- numpy array classes are different
- \\[left\\]: {klass1}
- \\[right\\]: {klass2}"""
- with pytest.raises(AssertionError, match=msg):
- tm.assert_almost_equal(a, b)
- def test_assert_almost_equal_value_mismatch1():
- msg = """numpy array are different
- numpy array values are different \\(66\\.66667 %\\)
- \\[left\\]: \\[nan, 2\\.0, 3\\.0\\]
- \\[right\\]: \\[1\\.0, nan, 3\\.0\\]"""
- with pytest.raises(AssertionError, match=msg):
- tm.assert_almost_equal(np.array([np.nan, 2, 3]), np.array([1, np.nan, 3]))
- def test_assert_almost_equal_value_mismatch2():
- msg = """numpy array are different
- numpy array values are different \\(50\\.0 %\\)
- \\[left\\]: \\[1, 2\\]
- \\[right\\]: \\[1, 3\\]"""
- with pytest.raises(AssertionError, match=msg):
- tm.assert_almost_equal(np.array([1, 2]), np.array([1, 3]))
- def test_assert_almost_equal_value_mismatch3():
- msg = """numpy array are different
- numpy array values are different \\(16\\.66667 %\\)
- \\[left\\]: \\[\\[1, 2\\], \\[3, 4\\], \\[5, 6\\]\\]
- \\[right\\]: \\[\\[1, 3\\], \\[3, 4\\], \\[5, 6\\]\\]"""
- with pytest.raises(AssertionError, match=msg):
- tm.assert_almost_equal(
- np.array([[1, 2], [3, 4], [5, 6]]), np.array([[1, 3], [3, 4], [5, 6]])
- )
- def test_assert_almost_equal_value_mismatch4():
- msg = """numpy array are different
- numpy array values are different \\(25\\.0 %\\)
- \\[left\\]: \\[\\[1, 2\\], \\[3, 4\\]\\]
- \\[right\\]: \\[\\[1, 3\\], \\[3, 4\\]\\]"""
- with pytest.raises(AssertionError, match=msg):
- tm.assert_almost_equal(np.array([[1, 2], [3, 4]]), np.array([[1, 3], [3, 4]]))
- def test_assert_almost_equal_shape_mismatch_override():
- msg = """Index are different
- Index shapes are different
- \\[left\\]: \\(2L*,\\)
- \\[right\\]: \\(3L*,\\)"""
- with pytest.raises(AssertionError, match=msg):
- tm.assert_almost_equal(np.array([1, 2]), np.array([3, 4, 5]), obj="Index")
- def test_assert_almost_equal_unicode():
- # see gh-20503
- msg = """numpy array are different
- numpy array values are different \\(33\\.33333 %\\)
- \\[left\\]: \\[á, à, ä\\]
- \\[right\\]: \\[á, à, å\\]"""
- with pytest.raises(AssertionError, match=msg):
- tm.assert_almost_equal(np.array(["á", "à", "ä"]), np.array(["á", "à", "å"]))
- def test_assert_almost_equal_timestamp():
- a = np.array([Timestamp("2011-01-01"), Timestamp("2011-01-01")])
- b = np.array([Timestamp("2011-01-01"), Timestamp("2011-01-02")])
- msg = """numpy array are different
- numpy array values are different \\(50\\.0 %\\)
- \\[left\\]: \\[2011-01-01 00:00:00, 2011-01-01 00:00:00\\]
- \\[right\\]: \\[2011-01-01 00:00:00, 2011-01-02 00:00:00\\]"""
- with pytest.raises(AssertionError, match=msg):
- tm.assert_almost_equal(a, b)
- def test_assert_almost_equal_iterable_length_mismatch():
- msg = """Iterable are different
- Iterable length are different
- \\[left\\]: 2
- \\[right\\]: 3"""
- with pytest.raises(AssertionError, match=msg):
- tm.assert_almost_equal([1, 2], [3, 4, 5])
- def test_assert_almost_equal_iterable_values_mismatch():
- msg = """Iterable are different
- Iterable values are different \\(50\\.0 %\\)
- \\[left\\]: \\[1, 2\\]
- \\[right\\]: \\[1, 3\\]"""
- with pytest.raises(AssertionError, match=msg):
- tm.assert_almost_equal([1, 2], [1, 3])
- subarr = np.empty(2, dtype=object)
- subarr[:] = [np.array([None, "b"], dtype=object), np.array(["c", "d"], dtype=object)]
- NESTED_CASES = [
- # nested array
- (
- np.array([np.array([50, 70, 90]), np.array([20, 30])], dtype=object),
- np.array([np.array([50, 70, 90]), np.array([20, 30])], dtype=object),
- ),
- # >1 level of nesting
- (
- np.array(
- [
- np.array([np.array([50, 70]), np.array([90])], dtype=object),
- np.array([np.array([20, 30])], dtype=object),
- ],
- dtype=object,
- ),
- np.array(
- [
- np.array([np.array([50, 70]), np.array([90])], dtype=object),
- np.array([np.array([20, 30])], dtype=object),
- ],
- dtype=object,
- ),
- ),
- # lists
- (
- np.array([[50, 70, 90], [20, 30]], dtype=object),
- np.array([[50, 70, 90], [20, 30]], dtype=object),
- ),
- # mixed array/list
- (
- np.array([np.array([1, 2, 3]), np.array([4, 5])], dtype=object),
- np.array([[1, 2, 3], [4, 5]], dtype=object),
- ),
- (
- np.array(
- [
- np.array([np.array([1, 2, 3]), np.array([4, 5])], dtype=object),
- np.array(
- [np.array([6]), np.array([7, 8]), np.array([9])], dtype=object
- ),
- ],
- dtype=object,
- ),
- np.array([[[1, 2, 3], [4, 5]], [[6], [7, 8], [9]]], dtype=object),
- ),
- # same-length lists
- (
- np.array([subarr, None], dtype=object),
- np.array([list([[None, "b"], ["c", "d"]]), None], dtype=object),
- ),
- # dicts
- (
- np.array([{"f1": 1, "f2": np.array(["a", "b"], dtype=object)}], dtype=object),
- np.array([{"f1": 1, "f2": np.array(["a", "b"], dtype=object)}], dtype=object),
- ),
- (
- np.array([{"f1": 1, "f2": np.array(["a", "b"], dtype=object)}], dtype=object),
- np.array([{"f1": 1, "f2": ["a", "b"]}], dtype=object),
- ),
- # array/list of dicts
- (
- np.array(
- [
- np.array(
- [{"f1": 1, "f2": np.array(["a", "b"], dtype=object)}], dtype=object
- ),
- np.array([], dtype=object),
- ],
- dtype=object,
- ),
- np.array([[{"f1": 1, "f2": ["a", "b"]}], []], dtype=object),
- ),
- ]
- @pytest.mark.filterwarnings("ignore:elementwise comparison failed:DeprecationWarning")
- @pytest.mark.parametrize("a,b", NESTED_CASES)
- def test_assert_almost_equal_array_nested(a, b):
- _assert_almost_equal_both(a, b)
|