Skip to content

Commit 5efce7b

Browse files
committed
Add tests and better docstring
1 parent 071a242 commit 5efce7b

File tree

4 files changed

+43
-15
lines changed

4 files changed

+43
-15
lines changed

pandas/conftest.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ def nselect_method(request):
402402
return request.param
403403

404404

405-
@pytest.fixture(params=[None, "ignore"])
405+
@pytest.fixture(params=[None, "ignore", "raise"])
406406
def na_action(request):
407407
"""
408408
Fixture for 'na_action' argument in map.

pandas/core/algorithms.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1639,7 +1639,9 @@ def map_array(
16391639
na_action : {None, 'ignore', 'raise'}, default None
16401640
If 'ignore', propagate NA values, without passing them to the
16411641
mapping correspondence. If 'raise', an error is raised when the
1642-
mapping correspondence does not cover all elements in the array.
1642+
array contains non-NA values which do not exist as keys in the mapping
1643+
correspondance (does not apply to function & dict-like mappers with
1644+
a '__missing__' attribute).
16431645
16441646
Returns
16451647
-------

pandas/core/series.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -4335,9 +4335,11 @@ def map(
43354335
----------
43364336
arg : function, collections.abc.Mapping subclass or Series
43374337
Mapping correspondence.
4338-
na_action : {None, 'ignore'}, default None
4338+
na_action : {None, 'ignore', 'raise'}, default None
43394339
If 'ignore', propagate NaN values, without passing them to the
4340-
mapping correspondence.
4340+
mapping correspondence. With 'raise' a missing value in the mapping
4341+
correspondence raises a ``ValueError`` instead of replacing it
4342+
with ``NaN``.
43414343
**kwargs
43424344
Additional keyword arguments to pass as keywords arguments to
43434345
`arg`.
@@ -4359,7 +4361,8 @@ def map(
43594361
Notes
43604362
-----
43614363
When ``arg`` is a dictionary, values in Series that are not in the
4362-
dictionary (as keys) are converted to ``NaN``. However, if the
4364+
dictionary (as keys) are converted to ``NaN``. This conversion
4365+
can be anticipated with ``na_action = 'raise'``. However, if the
43634366
dictionary is a ``dict`` subclass that defines ``__missing__`` (i.e.
43644367
provides a method for default values), then this default is used
43654368
rather than ``NaN``.

pandas/tests/series/methods/test_map.py

+33-10
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,19 @@ def test_map_dict_na_key():
322322
tm.assert_series_equal(result, expected)
323323

324324

325+
def test_map_missing_key(na_action):
326+
s = Series([1, 2, 42])
327+
mapping = {1: "a", 2: "b", 3: "c"}
328+
329+
if na_action == "raise":
330+
with pytest.raises(ValueError):
331+
s.map(mapping, na_action=na_action)
332+
else:
333+
expected = Series(["a", "b", np.nan])
334+
result = s.map(mapping, na_action=na_action)
335+
tm.assert_series_equal(result, expected)
336+
337+
325338
def test_map_defaultdict_na_key(na_action):
326339
# GH 48813
327340
s = Series([1, 2, np.nan])
@@ -380,7 +393,7 @@ def test_map_categorical_na_ignore(na_action, expected):
380393
tm.assert_series_equal(result, expected)
381394

382395

383-
def test_map_dict_subclass_with_missing():
396+
def test_map_dict_subclass_with_missing(na_action):
384397
"""
385398
Test Series.map with a dictionary subclass that defines __missing__,
386399
i.e. sets a default value (GH #15999).
@@ -392,30 +405,40 @@ def __missing__(self, key):
392405

393406
s = Series([1, 2, 3])
394407
dictionary = DictWithMissing({3: "three"})
395-
result = s.map(dictionary)
408+
result = s.map(dictionary, na_action=na_action) # also works with 'raise'
396409
expected = Series(["missing", "missing", "three"])
397410
tm.assert_series_equal(result, expected)
398411

399412

400-
def test_map_dict_subclass_without_missing():
413+
def test_map_dict_subclass_without_missing(na_action):
401414
class DictWithoutMissing(dict):
402415
pass
403416

404417
s = Series([1, 2, 3])
405418
dictionary = DictWithoutMissing({3: "three"})
406-
result = s.map(dictionary)
407-
expected = Series([np.nan, np.nan, "three"])
408-
tm.assert_series_equal(result, expected)
409419

420+
if na_action == "raise":
421+
with pytest.raises(ValueError):
422+
_ = s.map(dictionary, na_action=na_action)
423+
else:
424+
result = s.map(dictionary, na_action=na_action)
425+
expected = Series([np.nan, np.nan, "three"])
426+
tm.assert_series_equal(result, expected)
410427

411-
def test_map_abc_mapping(non_dict_mapping_subclass):
428+
429+
def test_map_abc_mapping(non_dict_mapping_subclass, na_action):
412430
# https://github.com/pandas-dev/pandas/issues/29733
413431
# Check collections.abc.Mapping support as mapper for Series.map
414432
s = Series([1, 2, 3])
415433
not_a_dictionary = non_dict_mapping_subclass({3: "three"})
416-
result = s.map(not_a_dictionary)
417-
expected = Series([np.nan, np.nan, "three"])
418-
tm.assert_series_equal(result, expected)
434+
435+
if na_action == "raise":
436+
with pytest.raises(ValueError):
437+
_ = s.map(not_a_dictionary, na_action=na_action)
438+
else:
439+
result = s.map(not_a_dictionary, na_action=na_action)
440+
expected = Series([np.nan, np.nan, "three"])
441+
tm.assert_series_equal(result, expected)
419442

420443

421444
def test_map_abc_mapping_with_missing(non_dict_mapping_subclass):

0 commit comments

Comments
 (0)