Skip to content

Commit 39c6957

Browse files
authored
BUG: use cmath to test complex number equality in pandas._testing (#36580)
1 parent 22c9d84 commit 39c6957

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

doc/source/whatsnew/v1.2.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ Numeric
325325
- Bug in :meth:`DataFrame.any` with ``axis=1`` and ``bool_only=True`` ignoring the ``bool_only`` keyword (:issue:`32432`)
326326
- Bug in :meth:`Series.equals` where a ``ValueError`` was raised when numpy arrays were compared to scalars (:issue:`35267`)
327327
- Bug in :class:`Series` where two :class:`Series` each have a :class:`DatetimeIndex` with different timezones having those indexes incorrectly changed when performing arithmetic operations (:issue:`33671`)
328+
- Bug in :meth:`pd._testing.assert_almost_equal` was incorrect for complex numeric types (:issue:`28235`)
328329
-
329330

330331
Conversion

pandas/_libs/testing.pyx

+12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import cmath
12
import math
23

34
import numpy as np
@@ -7,6 +8,7 @@ from numpy cimport import_array
78
import_array()
89

910
from pandas._libs.util cimport is_array
11+
from pandas._libs.lib import is_complex
1012

1113
from pandas.core.dtypes.common import is_dtype_equal
1214
from pandas.core.dtypes.missing import array_equivalent, isna
@@ -210,4 +212,14 @@ cpdef assert_almost_equal(a, b,
210212
f"with rtol={rtol}, atol={atol}")
211213
return True
212214

215+
if is_complex(a) and is_complex(b):
216+
if array_equivalent(a, b, strict_nan=True):
217+
# inf comparison
218+
return True
219+
220+
if not cmath.isclose(a, b, rel_tol=rtol, abs_tol=atol):
221+
assert False, (f"expected {b:.5f} but got {a:.5f}, "
222+
f"with rtol={rtol}, atol={atol}")
223+
return True
224+
213225
raise AssertionError(f"{a} != {b}")

pandas/tests/util/test_assert_almost_equal.py

+31
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,37 @@ def test_assert_not_almost_equal_numbers_rtol(a, b):
146146
_assert_not_almost_equal_both(a, b, rtol=0.05)
147147

148148

149+
@pytest.mark.parametrize(
150+
"a,b,rtol",
151+
[
152+
(1.00001, 1.00005, 0.001),
153+
(-0.908356 + 0.2j, -0.908358 + 0.2j, 1e-3),
154+
(0.1 + 1.009j, 0.1 + 1.006j, 0.1),
155+
(0.1001 + 2.0j, 0.1 + 2.001j, 0.01),
156+
],
157+
)
158+
def test_assert_almost_equal_complex_numbers(a, b, rtol):
159+
_assert_almost_equal_both(a, b, rtol=rtol)
160+
_assert_almost_equal_both(np.complex64(a), np.complex64(b), rtol=rtol)
161+
_assert_almost_equal_both(np.complex128(a), np.complex128(b), rtol=rtol)
162+
163+
164+
@pytest.mark.parametrize(
165+
"a,b,rtol",
166+
[
167+
(0.58310768, 0.58330768, 1e-7),
168+
(-0.908 + 0.2j, -0.978 + 0.2j, 0.001),
169+
(0.1 + 1j, 0.1 + 2j, 0.01),
170+
(-0.132 + 1.001j, -0.132 + 1.005j, 1e-5),
171+
(0.58310768j, 0.58330768j, 1e-9),
172+
],
173+
)
174+
def test_assert_not_almost_equal_complex_numbers(a, b, rtol):
175+
_assert_not_almost_equal_both(a, b, rtol=rtol)
176+
_assert_not_almost_equal_both(np.complex64(a), np.complex64(b), rtol=rtol)
177+
_assert_not_almost_equal_both(np.complex128(a), np.complex128(b), rtol=rtol)
178+
179+
149180
@pytest.mark.parametrize("a,b", [(0, 0), (0, 0.0), (0, np.float64(0)), (0.00000001, 0)])
150181
def test_assert_almost_equal_numbers_with_zeros(a, b):
151182
_assert_almost_equal_both(a, b)

0 commit comments

Comments
 (0)