Skip to content

Commit ed19fa3

Browse files
committed
BUG - In Series.map, only look for __missing__ if the mapper is a dict
subclass. TST - Add a test for the aforementioned bug
1 parent fc98bcb commit ed19fa3

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

pandas/core/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,7 @@ def _map_values(self, mapper, na_action=None):
12161216
# as we know that we are not going to have to yield
12171217
# python types
12181218
if isinstance(mapper, abc.Mapping):
1219-
if hasattr(mapper, "__missing__"):
1219+
if isinstance(mapper, dict) and hasattr(mapper, "__missing__"):
12201220
# If a dictionary subclass defines a default value method,
12211221
# convert mapper to a lookup function (GH #15999).
12221222
dict_with_default = mapper

pandas/tests/series/test_apply.py

+25
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,31 @@ def __len__(self):
629629
expected = Series([np.nan, np.nan, "three"])
630630
tm.assert_series_equal(result, expected)
631631

632+
def test_map_abc_mapping_with_missing(self):
633+
class NonDictMappingWithMissing(abc.Mapping):
634+
def __init__(self):
635+
self._data = {3: "three"}
636+
637+
def __getitem__(self, key):
638+
return self._data.__getitem__(key)
639+
640+
def __iter__(self):
641+
return self._data.__iter__()
642+
643+
def __len__(self):
644+
return self._data.__len__()
645+
646+
def __missing__(self, key):
647+
return "missing"
648+
649+
s = Series([1, 2, 3])
650+
not_a_dictionary = NonDictMappingWithMissing()
651+
result = s.map(not_a_dictionary)
652+
# __missing__ is a dict concept, not a Mapping concept,
653+
# so it should not change the result!
654+
expected = Series([np.nan, np.nan, "three"])
655+
tm.assert_series_equal(result, expected)
656+
632657
def test_map_box(self):
633658
vals = [pd.Timestamp("2011-01-01"), pd.Timestamp("2011-01-02")]
634659
s = pd.Series(vals)

0 commit comments

Comments
 (0)