Skip to content

Commit addfd75

Browse files
committed
[BUG]: Isin converted floats unnecessarily to int causing rounding issues
1 parent bdb00f2 commit addfd75

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

doc/source/whatsnew/v1.2.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ Reshaping
557557
- Bug in :meth:`DataFrame.combine_first()` caused wrong alignment with dtype ``string`` and one level of ``MultiIndex`` containing only ``NA`` (:issue:`37591`)
558558
- Fixed regression in :func:`merge` on merging DatetimeIndex with empty DataFrame (:issue:`36895`)
559559
- Bug in :meth:`DataFrame.apply` not setting index of return value when ``func`` return type is ``dict`` (:issue:`37544`)
560+
- Bug in :meth:`Series.isin` cast ``float`` unnecessarily to ``int`` when :class:`Series` to look in was from dtype ``int`` (:issue:`19356`)
560561

561562
Sparse
562563
^^^^^^

pandas/core/algorithms.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
construct_1d_object_array_from_listlike,
2020
infer_dtype_from_array,
2121
maybe_promote,
22+
maybe_upcast,
2223
)
2324
from pandas.core.dtypes.common import (
2425
ensure_float64,
@@ -431,6 +432,13 @@ def isin(comps: AnyArrayLike, values: AnyArrayLike) -> np.ndarray:
431432
return cast("Categorical", comps).isin(values)
432433

433434
comps, dtype = _ensure_data(comps)
435+
if is_numeric_dtype(comps):
436+
try:
437+
# Try finding a dtype which would not change our values
438+
values, _ = maybe_upcast(values, dtype=dtype)
439+
dtype = values.dtype
440+
except (ValueError, TypeError):
441+
pass
434442
values, _ = _ensure_data(values, dtype=dtype)
435443

436444
# faster for larger cases to use np.in1d
@@ -445,7 +453,7 @@ def isin(comps: AnyArrayLike, values: AnyArrayLike) -> np.ndarray:
445453
f = lambda c, v: np.logical_or(np.in1d(c, v), np.isnan(c))
446454
else:
447455
f = np.in1d
448-
elif is_integer_dtype(comps):
456+
elif is_integer_dtype(comps) and is_integer_dtype(values):
449457
try:
450458
values = values.astype("int64", copy=False)
451459
comps = comps.astype("int64", copy=False)
@@ -454,7 +462,7 @@ def isin(comps: AnyArrayLike, values: AnyArrayLike) -> np.ndarray:
454462
values = values.astype(object)
455463
comps = comps.astype(object)
456464

457-
elif is_float_dtype(comps):
465+
elif is_numeric_dtype(comps) or is_numeric_dtype(values):
458466
try:
459467
values = values.astype("float64", copy=False)
460468
comps = comps.astype("float64", copy=False)

pandas/tests/series/methods/test_isin.py

+8
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,14 @@ def test_isin_read_only(self):
9090
expected = Series([True, True, True])
9191
tm.assert_series_equal(result, expected)
9292

93+
@pytest.mark.parametrize("values", [[-9., 0.], [-9, 0]])
94+
def test_isin_float_in_int_series(self, values):
95+
# GH: 19356
96+
ser = Series(values)
97+
result = ser.isin([-9, -0.5])
98+
expected = Series([True, False])
99+
tm.assert_series_equal(result, expected)
100+
93101

94102
@pytest.mark.slow
95103
def test_isin_large_series_mixed_dtypes_and_nan():

0 commit comments

Comments
 (0)