Skip to content

Commit 6d6fc84

Browse files
committed
BUG: Don't with empty Series for .isin
Empty Series initializes to float64, even when the data type is object for .isin, leading to an error with membership. Closes pandas-devgh-16991.
1 parent fcb0263 commit 6d6fc84

File tree

6 files changed

+35
-2
lines changed

6 files changed

+35
-2
lines changed

doc/source/whatsnew/v0.21.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,4 @@ Categorical
204204
Other
205205
^^^^^
206206
- Bug in :func:`eval` where the ``inplace`` parameter was being incorrectly handled (:issue:`16732`)
207+
- Bug in ``.isin()`` in which checking membership in empty ``Series`` objects raised an error (:issue:`16991`)

pandas/core/algorithms.py

+2
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ def _ensure_data(values, dtype=None):
6565

6666
# we check some simple dtypes first
6767
try:
68+
if is_object_dtype(dtype):
69+
return _ensure_object(np.asarray(values)), 'object', 'object'
6870
if is_bool_dtype(values) or is_bool_dtype(dtype):
6971
# we are actually coercing to uint64
7072
# until our algos suppport uint8 directly (see TODO)

pandas/tests/frame/test_analytics.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -1151,10 +1151,13 @@ def test_isin(self):
11511151
expected = DataFrame([df.loc[s].isin(other) for s in df.index])
11521152
tm.assert_frame_equal(result, expected)
11531153

1154-
def test_isin_empty(self):
1154+
@pytest.mark.parametrize("empty", [[], Series(), np.array([])])
1155+
def test_isin_empty(self, empty):
1156+
# see gh-16991
11551157
df = DataFrame({'A': ['a', 'b', 'c'], 'B': ['a', 'e', 'f']})
1156-
result = df.isin([])
11571158
expected = pd.DataFrame(False, df.index, df.columns)
1159+
1160+
result = df.isin(empty)
11581161
tm.assert_frame_equal(result, expected)
11591162

11601163
def test_isin_dict(self):

pandas/tests/indexes/test_base.py

+9
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,15 @@ def check_idx(idx):
14071407
# Float64Index overrides isin, so must be checked separately
14081408
check_idx(Float64Index([1.0, 2.0, 3.0, 4.0]))
14091409

1410+
@pytest.mark.parametrize("empty", [[], Series(), np.array([])])
1411+
def test_isin_empty(self, empty):
1412+
# see gh-16991
1413+
idx = Index(["a", "b"])
1414+
expected = np.array([False, False])
1415+
1416+
result = idx.isin(empty)
1417+
tm.assert_numpy_array_equal(expected, result)
1418+
14101419
def test_boolean_cmp(self):
14111420
values = [1, 2, 3, 4]
14121421

pandas/tests/series/test_analytics.py

+9
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,15 @@ def test_isin_with_i8(self):
11351135
result = s.isin(s[0:2])
11361136
assert_series_equal(result, expected)
11371137

1138+
@pytest.mark.parametrize("empty", [[], Series(), np.array([])])
1139+
def test_isin_empty(self, empty):
1140+
# see gh-16991
1141+
s = Series(["a", "b"])
1142+
expected = Series([False, False])
1143+
1144+
result = s.isin(empty)
1145+
tm.assert_series_equal(expected, result)
1146+
11381147
def test_timedelta64_analytics(self):
11391148
from pandas import date_range
11401149

pandas/tests/test_algos.py

+9
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,15 @@ def test_categorical_from_codes(self):
597597
result = algos.isin(Sd, St)
598598
tm.assert_numpy_array_equal(expected, result)
599599

600+
@pytest.mark.parametrize("empty", [[], pd.Series(), np.array([])])
601+
def test_empty(self, empty):
602+
# see gh-16991
603+
vals = pd.Index(["a", "b"])
604+
expected = np.array([False, False])
605+
606+
result = algos.isin(vals, empty)
607+
tm.assert_numpy_array_equal(expected, result)
608+
600609

601610
class TestValueCounts(object):
602611

0 commit comments

Comments
 (0)