From 5849db59c0c54232891a13aa9d28ee82c5a14bfd Mon Sep 17 00:00:00 2001 From: Joerg Rings Date: Mon, 4 Apr 2016 20:33:06 -0500 Subject: [PATCH 1/2] API: map() on Index returns an Index, not array [ENH] Using _shallow_copy_with_infer, additional test for type change and attribute conservation TST: Tests for various index types REF: Move to tm.assert_index_equal DOC: docstring for the map function --- doc/source/whatsnew/v0.18.1.txt | 2 ++ pandas/indexes/base.py | 7 ++++--- pandas/tests/indexes/test_base.py | 35 +++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/doc/source/whatsnew/v0.18.1.txt b/doc/source/whatsnew/v0.18.1.txt index 7f74d8a769e4b..9922b326b6424 100644 --- a/doc/source/whatsnew/v0.18.1.txt +++ b/doc/source/whatsnew/v0.18.1.txt @@ -408,6 +408,8 @@ New behaviour: np.cumsum(sp, axis=0) +- ``map`` on an ``Index`` now returns an ``Index``, not an array (:issue:`12766`) + .. _whatsnew_0181.apply_resample: Using ``.apply`` on groupby resampling diff --git a/pandas/indexes/base.py b/pandas/indexes/base.py index 1c24a0db34b2b..70faa89a57309 100644 --- a/pandas/indexes/base.py +++ b/pandas/indexes/base.py @@ -2427,7 +2427,7 @@ def groupby(self, values): def map(self, mapper): """ - Apply mapper function to its values. + Apply mapper function to an index Parameters ---------- @@ -2436,9 +2436,10 @@ def map(self, mapper): Returns ------- - applied : array + An Index reflecting an appropriate Index with the mapper + function applied """ - return self._arrmap(self.values, mapper) + return self._shallow_copy_with_infer(self._arrmap(self.values, mapper)) def isin(self, values, level=None): """ diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index 21471b1883209..a5a1cfbc6d110 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -1744,6 +1744,41 @@ def test_string_index_repr(self): self.assertEqual(coerce(idx), expected) + def test_map(self): + + # Applying a function to the Index + df = pd.DataFrame([[0, 1], [2, 3]], columns=['c1', 'c2'], index=['i1', 'i2']) + df.index.name = "Numbering" + df.index = df.index.map(lambda x: x.upper()) + self.assertTrue(df.index.equals(Index(['I1', 'I2']))) + self.assertEqual(df.index.name, "Numbering") + + testIdx = self.unicodeIndex.map(lambda x: len(x)) + tm.assert_index_equal(testIdx, Int64Index([10]*100)) + + testIdx = self.strIndex.map(lambda x: len(x)) + tm.assert_index_equal(testIdx, Int64Index([10]*100)) + + testIdx = self.dateIndex.map(lambda x: x + timedelta(days=1)) + tm.assert_index_equal( + testIdx, DatetimeIndex([dt + timedelta(days=1) for dt in tm.makeDateIndex(100)])) + + testIdx = self.periodIndex.map(lambda x: x.to_timestamp()) + tm.assert_index_equal(testIdx, self.dateIndex) + + testIdx = self.intIndex.map(lambda x: str(x)) + tm.assert_index_equal(testIdx, Index([str(i) for i in range(100)])) + + testIdx = self.floatIndex.map(lambda x: -1 if x < 0 else 1) + self.assertEqual(len(testIdx), 100) + self.assertTrue(isinstance(testIdx, Int64Index)) + self.assertTrue(set(testIdx == {-1, 1})) + + testIdx = self.boolIndex.map(lambda x: not x) + tm.assert_index_equal(testIdx, Index([False, True])) + + testIdx = self.catIndex.map(lambda x: len(x)) + class TestMixedIntIndex(Base, tm.TestCase): # Mostly the tests from common.py for which the results differ From c30c8624d4ceee6f8ab2d164409ed164902e015b Mon Sep 17 00:00:00 2001 From: Joerg Rings Date: Wed, 19 Oct 2016 21:40:12 -0500 Subject: [PATCH 2/2] Moving tests --- pandas/tests/indexes/common.py | 38 +++++++++++++++++++++++ pandas/tests/indexes/test_base.py | 35 --------------------- pandas/tests/indexes/test_datetimelike.py | 2 ++ 3 files changed, 40 insertions(+), 35 deletions(-) diff --git a/pandas/tests/indexes/common.py b/pandas/tests/indexes/common.py index 773f20532e4ff..98d37eb632947 100644 --- a/pandas/tests/indexes/common.py +++ b/pandas/tests/indexes/common.py @@ -852,3 +852,41 @@ def test_fillna(self): expected[1] = True self.assert_numpy_array_equal(idx._isnan, expected) self.assertTrue(idx.hasnans) + + def test_map(self): + for name, index in self.indices.items(): + if len(index) == 0 or isinstance(index, MultiIndex): + pass + else: + # Applying a function to the Index + index = index.map(lambda x: x) + print(name, index) + self.assertTrue(isinstance(index, Index)) + #self.assertTrue(index.equals(Index(['I1', 'I2']))) + #self.assertEqual(index.name, "Numbering") +# + #testIdx = self.unicodeIndex.map(lambda x: len(x)) + #tm.assert_index_equal(testIdx, Int64Index([10]*100)) +# + #testIdx = self.strIndex.map(lambda x: len(x)) + #tm.assert_index_equal(testIdx, Int64Index([10]*100)) +# + #testIdx = self.dateIndex.map(lambda x: x + timedelta(days=1)) + #tm.assert_index_equal( + # testIdx, DatetimeIndex([dt + timedelta(days=1) for dt in tm.makeDateIndex(100)])) +# + #testIdx = self.periodIndex.map(lambda x: x.to_timestamp()) + #tm.assert_index_equal(testIdx, self.dateIndex) +# + #testIdx = self.intIndex.map(lambda x: str(x)) + #tm.assert_index_equal(testIdx, Index([str(i) for i in range(100)])) +# + #testIdx = self.floatIndex.map(lambda x: -1 if x < 0 else 1) + #self.assertEqual(len(testIdx), 100) + #self.assertTrue(isinstance(testIdx, Int64Index)) + #self.assertTrue(set(testIdx == {-1, 1})) +# + #testIdx = self.boolIndex.map(lambda x: not x) + #tm.assert_index_equal(testIdx, Index([False, True])) +# + #testIdx = self.catIndex.map(lambda x: len(x)) diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index a5a1cfbc6d110..21471b1883209 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -1744,41 +1744,6 @@ def test_string_index_repr(self): self.assertEqual(coerce(idx), expected) - def test_map(self): - - # Applying a function to the Index - df = pd.DataFrame([[0, 1], [2, 3]], columns=['c1', 'c2'], index=['i1', 'i2']) - df.index.name = "Numbering" - df.index = df.index.map(lambda x: x.upper()) - self.assertTrue(df.index.equals(Index(['I1', 'I2']))) - self.assertEqual(df.index.name, "Numbering") - - testIdx = self.unicodeIndex.map(lambda x: len(x)) - tm.assert_index_equal(testIdx, Int64Index([10]*100)) - - testIdx = self.strIndex.map(lambda x: len(x)) - tm.assert_index_equal(testIdx, Int64Index([10]*100)) - - testIdx = self.dateIndex.map(lambda x: x + timedelta(days=1)) - tm.assert_index_equal( - testIdx, DatetimeIndex([dt + timedelta(days=1) for dt in tm.makeDateIndex(100)])) - - testIdx = self.periodIndex.map(lambda x: x.to_timestamp()) - tm.assert_index_equal(testIdx, self.dateIndex) - - testIdx = self.intIndex.map(lambda x: str(x)) - tm.assert_index_equal(testIdx, Index([str(i) for i in range(100)])) - - testIdx = self.floatIndex.map(lambda x: -1 if x < 0 else 1) - self.assertEqual(len(testIdx), 100) - self.assertTrue(isinstance(testIdx, Int64Index)) - self.assertTrue(set(testIdx == {-1, 1})) - - testIdx = self.boolIndex.map(lambda x: not x) - tm.assert_index_equal(testIdx, Index([False, True])) - - testIdx = self.catIndex.map(lambda x: len(x)) - class TestMixedIntIndex(Base, tm.TestCase): # Mostly the tests from common.py for which the results differ diff --git a/pandas/tests/indexes/test_datetimelike.py b/pandas/tests/indexes/test_datetimelike.py index 7502a4ce26b04..34758a2b7f04b 100644 --- a/pandas/tests/indexes/test_datetimelike.py +++ b/pandas/tests/indexes/test_datetimelike.py @@ -1149,3 +1149,5 @@ def test_fillna_timedelta(self): exp = pd.Index( [pd.Timedelta('1 day'), 'x', pd.Timedelta('3 day')], dtype=object) self.assert_index_equal(idx.fillna('x'), exp) + +