Skip to content

Commit a858467

Browse files
nateyoderjreback
authored andcommitted
Address comments from @jreback add new tests; skip tests on IntervalIndex
1 parent 73c276b commit a858467

File tree

8 files changed

+86
-28
lines changed

8 files changed

+86
-28
lines changed

pandas/core/base.py

+21
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,27 @@ def _reduce(self, op, name, axis=0, skipna=True, numeric_only=None,
839839
return func(**kwds)
840840

841841
def _map_values(self, values, arg, na_action=None):
842+
"""An internal function that maps values using the input
843+
correspondence (which can be a dict, Series, or function).
844+
845+
Parameters
846+
----------
847+
values : np.ndarray
848+
The values to be mapped
849+
arg : function, dict, or Series
850+
The input correspondence object
851+
na_action : {None, 'ignore'}
852+
If 'ignore', propagate NA values, without passing them to the
853+
mapping function
854+
855+
Returns
856+
-------
857+
applied : {Index, MultiIndex}, inferred
858+
The output of the mapping function applied to the index.
859+
If the function returns a tuple with more than one element
860+
a MultiIndex will be returned.
861+
862+
"""
842863
if is_extension_type(self.dtype):
843864
if na_action is not None:
844865
raise NotImplementedError

pandas/core/indexes/base.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -2827,7 +2827,7 @@ def get_indexer_for(self, target, **kwargs):
28272827
28282828
Parameters
28292829
----------
2830-
data : {dict, DictWithoutMissing}
2830+
data : dict
28312831
The dictionary from which to extract the values
28322832
28332833
Returns
@@ -2904,8 +2904,14 @@ def map(self, arg, na_action=None):
29042904
self.values, arg, na_action=na_action)
29052905
attributes = self._get_attributes_dict()
29062906
if new_values.size and isinstance(new_values[0], tuple):
2907+
if isinstance(self, MultiIndex):
2908+
names = self.names
2909+
elif attributes.get('name'):
2910+
names = [attributes.get('name')] * len(new_values[0])
2911+
else:
2912+
names = None
29072913
return MultiIndex.from_tuples(new_values,
2908-
names=attributes.get('name'))
2914+
names=names)
29092915

29102916
attributes['copy'] = False
29112917
return Index(new_values, **attributes)

pandas/tests/indexes/common.py

+26
Original file line numberDiff line numberDiff line change
@@ -996,3 +996,29 @@ def test_searchsorted_monotonic(self, indices):
996996
# non-monotonic should raise.
997997
with pytest.raises(ValueError):
998998
indices._searchsorted_monotonic(value, side='left')
999+
1000+
def test_map(self):
1001+
index = self.create_index()
1002+
# From output of UInt64Index mapping can't infer that we
1003+
# shouldn't default to Int64
1004+
if isinstance(index, UInt64Index):
1005+
expected = Index(index.values.tolist())
1006+
else:
1007+
expected = index
1008+
1009+
tm.assert_index_equal(index.map(lambda x: x), expected)
1010+
1011+
identity_dict = {x: x for x in index}
1012+
tm.assert_index_equal(index.map(identity_dict), expected)
1013+
1014+
# Use values to work around MultiIndex instantiation of series
1015+
identity_series = Series(expected.values, index=index)
1016+
tm.assert_index_equal(index.map(identity_series), expected)
1017+
1018+
# empty mappable
1019+
nan_index = pd.Index([np.nan] * len(index))
1020+
series_map = pd.Series()
1021+
tm.assert_index_equal(index.map(series_map), nan_index)
1022+
1023+
dict_map = {}
1024+
tm.assert_index_equal(index.map(dict_map), nan_index)

pandas/tests/indexes/datetimelike.py

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
""" generic datetimelike tests """
2-
2+
import pandas as pd
33
from .common import Base
44
import pandas.util.testing as tm
55

@@ -38,3 +38,24 @@ def test_view(self, indices):
3838
i_view = i.view(self._holder)
3939
result = self._holder(i)
4040
tm.assert_index_equal(result, i_view)
41+
42+
def test_map(self):
43+
expected = self.index + 1
44+
tm.assert_index_equal(self.index.map(lambda x: x + 1), expected)
45+
46+
series_map = pd.Series(expected, self.index)
47+
tm.assert_index_equal(self.index.map(series_map), expected)
48+
49+
dict_map = {i: e for e, i in zip(expected, self.index)}
50+
tm.assert_index_equal(self.index.map(dict_map), expected)
51+
52+
# map to NaT
53+
result = self.index.map(lambda x: pd.NaT if x == self.index[0] else x)
54+
expected = pd.Index([pd.NaT] + self.index[1:].tolist())
55+
tm.assert_index_equal(result, expected)
56+
57+
series_map = pd.Series(expected, self.index)
58+
tm.assert_index_equal(self.index.map(series_map), expected)
59+
60+
dict_map = {i: e for e, i in zip(expected, self.index)}
61+
tm.assert_index_equal(self.index.map(dict_map), expected)

pandas/tests/indexes/datetimes/test_datetimelike.py

+1-24
Original file line numberDiff line numberDiff line change
@@ -78,27 +78,4 @@ def test_union(self):
7878
assert tm.equalContents(result, everything)
7979

8080
def test_map(self):
81-
expected = self.index + 1
82-
tm.assert_index_equal(self.index.map(lambda x: x + 1), expected)
83-
84-
series_map = pd.Series(expected, self.index)
85-
tm.assert_index_equal(self.index.map(series_map), expected)
86-
87-
dict_map = {i: e for e, i in zip(expected, self.index)}
88-
tm.assert_index_equal(self.index.map(dict_map), expected)
89-
90-
# empty mappable
91-
nan_index = Index([pd.np.nan] * len(self.index))
92-
series_map = pd.Series()
93-
tm.assert_index_equal(self.index.map(series_map), nan_index)
94-
dict_map = {}
95-
tm.assert_index_equal(self.index.map(dict_map), nan_index)
96-
97-
# map to NaT
98-
result = self.index.map(lambda x: pd.NaT if x == self.index[0] else x)
99-
expected = Index([pd.NaT] + self.index[1:].tolist())
100-
tm.assert_index_equal(result, expected)
101-
series_map = pd.Series(expected, self.index)
102-
tm.assert_index_equal(self.index.map(series_map), expected)
103-
dict_map = {i: e for e, i in zip(expected, self.index)}
104-
tm.assert_index_equal(self.index.map(dict_map), expected)
81+
super(TestDatetimeIndex, self).test_map()

pandas/tests/indexes/period/test_period.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,9 @@ def test_pickle_freq(self):
788788
assert new_prng.freq == offsets.MonthEnd()
789789
assert new_prng.freqstr == 'M'
790790

791-
def test_map_with_ordinal(self):
791+
def test_map(self):
792+
super(TestPeriodIndex, self).test_map()
793+
792794
index = PeriodIndex([2005, 2007, 2009], freq='A')
793795
result = index.map(lambda x: x.ordinal)
794796
exp = Index([x.ordinal for x in index])

pandas/tests/indexes/test_interval.py

+4
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,10 @@ def test_repr_max_seq_item_setting(self):
395395
def test_repr_roundtrip(self):
396396
super(TestIntervalIndex, self).test_repr_roundtrip()
397397

398+
@pytest.mark.xfail(reason='get_indexer behavior does not currently work')
399+
def test_map(self):
400+
super(TestIntervalIndex, self).test_map()
401+
398402
def test_get_item(self):
399403
i = IntervalIndex.from_arrays((0, 1, np.nan), (1, 2, np.nan),
400404
closed='right')

pandas/tests/indexes/timedeltas/test_timedelta.py

+1
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ def test_misc_coverage(self):
300300
assert not idx.equals(list(non_td))
301301

302302
def test_map(self):
303+
super(TestTimedeltaIndex, self).test_map()
303304

304305
rng = timedelta_range('1 day', periods=10)
305306

0 commit comments

Comments
 (0)