Skip to content

Commit aed64e8

Browse files
authored
BUG: fix isin with nans and large arrays (#36266)
1 parent 3e1cc56 commit aed64e8

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

doc/source/whatsnew/v1.1.3.rst

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Bug fixes
4747
- Bug in :class:`Series` constructor where integer overflow would occur for sufficiently large scalar inputs when an index was provided (:issue:`36291`)
4848
- Bug in :meth:`DataFrame.sort_values` raising an ``AttributeError`` when sorting on a key that casts column to categorical dtype (:issue:`36383`)
4949
- Bug in :meth:`DataFrame.stack` raising a ``ValueError`` when stacking :class:`MultiIndex` columns based on position when the levels had duplicate names (:issue:`36353`)
50+
- Bug in :meth:`Series.isin` and :meth:`DataFrame.isin` when using ``NaN`` and a row length above 1,000,000 (:issue:`22205`)
5051

5152
.. ---------------------------------------------------------------------------
5253

pandas/core/algorithms.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,12 @@ def isin(comps: AnyArrayLike, values: AnyArrayLike) -> np.ndarray:
440440
# GH16012
441441
# Ensure np.in1d doesn't get object types or it *may* throw an exception
442442
if len(comps) > 1_000_000 and not is_object_dtype(comps):
443-
f = np.in1d
443+
# If the the values include nan we need to check for nan explicitly
444+
# since np.nan it not equal to np.nan
445+
if np.isnan(values).any():
446+
f = lambda c, v: np.logical_or(np.in1d(c, v), np.isnan(c))
447+
else:
448+
f = np.in1d
444449
elif is_integer_dtype(comps):
445450
try:
446451
values = values.astype("int64", copy=False)

pandas/tests/test_algos.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,6 @@ def test_i8(self):
801801
tm.assert_numpy_array_equal(result, expected)
802802

803803
def test_large(self):
804-
805804
s = pd.date_range("20000101", periods=2000000, freq="s").values
806805
result = algos.isin(s, s[0:2])
807806
expected = np.zeros(len(s), dtype=bool)
@@ -841,6 +840,23 @@ def test_same_nan_is_in(self):
841840
result = algos.isin(comps, values)
842841
tm.assert_numpy_array_equal(expected, result)
843842

843+
def test_same_nan_is_in_large(self):
844+
# https://github.com/pandas-dev/pandas/issues/22205
845+
s = np.tile(1.0, 1_000_001)
846+
s[0] = np.nan
847+
result = algos.isin(s, [np.nan, 1])
848+
expected = np.ones(len(s), dtype=bool)
849+
tm.assert_numpy_array_equal(result, expected)
850+
851+
def test_same_nan_is_in_large_series(self):
852+
# https://github.com/pandas-dev/pandas/issues/22205
853+
s = np.tile(1.0, 1_000_001)
854+
series = pd.Series(s)
855+
s[0] = np.nan
856+
result = series.isin([np.nan, 1])
857+
expected = pd.Series(np.ones(len(s), dtype=bool))
858+
tm.assert_series_equal(result, expected)
859+
844860
def test_same_object_is_in(self):
845861
# GH 22160
846862
# there could be special treatment for nans

0 commit comments

Comments
 (0)