Skip to content

Commit 7350469

Browse files
committed
BUG: avoid float upcast when mixing signed/unsigned ints in isin (tests added)
1 parent db31f6a commit 7350469

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

pandas/core/algorithms.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -522,11 +522,18 @@ def isin(comps: ListLike, values: ListLike) -> npt.NDArray[np.bool_]:
522522
if (
523523
len(values) > 0
524524
and values.dtype.kind in "iufcb"
525-
and not is_signed_integer_dtype(comps)
526-
and not is_dtype_equal(values, comps)
525+
# If the dtypes differ and either side is unsigned integer,
526+
# prefer object dtype to avoid unsafe upcast to float64 that
527+
# can lose precision for large 64-bit integers.
528+
and (not is_dtype_equal(values, comps))
529+
and (
530+
(not is_signed_integer_dtype(comps))
531+
or (not is_signed_integer_dtype(values))
532+
)
527533
):
528-
# GH#46485 Use object to avoid upcast to float64 later
529-
# TODO: Share with _find_common_type_compat
534+
# GH#46485: Use object to avoid upcast to float64 later
535+
# Ensure symmetric behavior when mixing signed and unsigned
536+
# integer dtypes.
530537
values = construct_1d_object_array_from_listlike(orig_values)
531538

532539
elif isinstance(values, ABCMultiIndex):

pandas/tests/series/methods/test_isin.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,16 @@ def test_isin_filtering_on_iterable(data, isin):
267267
expected_result = Series([True, True, False])
268268

269269
tm.assert_series_equal(result, expected_result)
270+
271+
272+
def test_isin_int64_vs_uint64_mismatch():
273+
# Regression test for mixing signed int64 Series with uint64 values
274+
# Ensure we do not implicitly upcast to float64 and return incorrect True
275+
# related to GH# (user report)
276+
ser = Series([1378774140726870442], dtype=np.int64)
277+
vals = [np.uint64(1378774140726870528)]
278+
279+
res = ser.isin(vals)
280+
# different values -> should be False
281+
expected = Series([False])
282+
tm.assert_series_equal(res, expected)

0 commit comments

Comments
 (0)