Closed
Description
Code Sample, a copy-pastable example if possible
import pandas as pd
from collections import UserDict, Counter
class MissingDict(UserDict):
def __missing__(self, key):
return key
s = pd.Series(list("aab"))
s.map(Counter({"a": 1}))
# 0 1
# 1 1
# 2 0
# dtype: int64
s.map(MissingDict({"a": "c"}))
# <ipython-input-48-6cd4b0d364c9> in <module>
# ----> 1 s.map(MissingDict({"a": "c"}))
# /usr/local/lib/python3.7/site-packages/pandas/core/series.py in map(self, arg, na_action)
# 3826 dtype: object
# 3827 """
# -> 3828 new_values = super()._map_values(arg, na_action=na_action)
# 3829 return self._constructor(new_values, index=self.index).__finalize__(self)
# 3830
# /usr/local/lib/python3.7/site-packages/pandas/core/base.py in _map_values(self, mapper, na_action)
# 1298
# 1299 # mapper is a function
# -> 1300 new_values = map_f(values, mapper)
# 1301
# 1302 return new_values
# pandas/_libs/lib.pyx in pandas._libs.lib.map_infer()
# TypeError: 'MissingDict' object is not callable
Problem description
Series.map
can sometimes take Mapping subclasses other than dict
, but not always. I think it would make sense if any object that satisfied isinstance(x, collections.abc.Mapping)
could be used as a mapping. I came across this while trying to use map where I only wanted values present as keys in the mapping to change (I went for s.map(lambda x: {"a": "b"}.get(x, x))
as a workaround).
collections.Counter
and collections.defaultdict
work fine, which made me expect other Mapping
s would as well.
Expected Output
I expected s.map(MissingDict({"a": "c"}))
to do something like:
s.map(lambda x: MissingDict({"a": "c"})[x])
# 0 c
# 1 c
# 2 b
# dtype: object
Output of pd.show_versions()
INSTALLED VERSIONS
------------------
commit : None
python : 3.7.4.final.0
python-bits : 64
OS : Darwin
OS-release : 18.7.0
machine : x86_64
processor : i386
byteorder : little
LC_ALL : None
LANG : en_US.UTF-8
LOCALE : en_US.UTF-8
pandas : 0.25.3
numpy : 1.17.4
pytz : 2018.9
dateutil : 2.7.5
pip : 19.3.1
setuptools : 41.6.0
Cython : 0.29.14
pytest : 5.2.2
hypothesis : 4.44.1
sphinx : 2.2.1
blosc : None
feather : None
xlsxwriter : None
lxml.etree : 4.4.1
html5lib : 1.0.1
pymysql : None
psycopg2 : None
jinja2 : 2.10.1
IPython : 7.9.0
pandas_datareader: None
bs4 : 4.8.1
bottleneck : None
fastparquet : 0.3.2
gcsfs : None
lxml.etree : 4.4.1
matplotlib : 3.0.3
numexpr : 2.7.0
odfpy : None
openpyxl : 2.6.2
pandas_gbq : None
pyarrow : 0.15.1
pytables : None
s3fs : None
scipy : 1.3.2
sqlalchemy : None
tables : 3.6.1
xarray : 0.14.0
xlrd : 1.2.0
xlwt : None
xlsxwriter : None