Skip to content

Commit 7b47d31

Browse files
committed
Merge pull request #4136 from cpcloud/period-index-repr
BUG: period idx str map incorrectly returns a str repr of itself when ind.map(str) is called
2 parents 2f88dca + 4fddb29 commit 7b47d31

File tree

4 files changed

+38
-6
lines changed

4 files changed

+38
-6
lines changed

doc/source/release.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ pandas 0.13
4848
with a different block ordering (:issue:`4096`)
4949
- The ``by`` argument now works correctly with the ``layout`` argument
5050
(:issue:`4102`, :issue:`4014`) in ``*.hist`` plotting methods
51+
- Fixed bug in ``PeriodIndex.map`` where using ``str`` would return the str
52+
representation of the index (:issue:`4136`)
5153

5254
pandas 0.12
5355
===========

doc/source/v0.13.0.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ Bug Fixes
2424
- The ``by`` argument now works correctly with the ``layout`` argument
2525
(:issue:`4102`, :issue:`4014`) in ``*.hist`` plotting methods
2626

27+
- Fixed bug in ``PeriodIndex.map`` where using ``str`` would return the str
28+
representation of the index (:issue:`4136`)
29+
2730
See the :ref:`full release notes
2831
<release>` or issue tracker
2932
on GitHub for a complete list.

pandas/tseries/period.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,6 @@ def dt64arr_to_periodarr(data, freq, tz):
469469

470470
# --- Period index sketch
471471

472-
473472
def _period_index_cmp(opname):
474473
"""
475474
Wrap comparison operations to convert datetime-like to datetime64
@@ -493,6 +492,7 @@ def wrapper(self, other):
493492
return result
494493
return wrapper
495494

495+
496496
class PeriodIndex(Int64Index):
497497
"""
498498
Immutable ndarray holding ordinal values indicating regular periods in
@@ -791,10 +791,12 @@ def to_datetime(self, dayfirst=False):
791791
# Especially important for group-by functionality
792792
def map(self, f):
793793
try:
794-
return f(self)
795-
except:
796-
values = self._get_object_array()
797-
return _algos.arrmap_object(values, f)
794+
result = f(self)
795+
if not isinstance(result, np.ndarray):
796+
raise TypeError
797+
return result
798+
except Exception:
799+
return _algos.arrmap_object(self.asobject, f)
798800

799801
def _get_object_array(self):
800802
freq = self.freq
@@ -1169,6 +1171,7 @@ def __setstate__(self, state):
11691171
else: # pragma: no cover
11701172
np.ndarray.__setstate__(self, state)
11711173

1174+
11721175
def _get_ordinal_range(start, end, periods, freq):
11731176
if com._count_not_none(start, end, periods) < 2:
11741177
raise ValueError('Must specify 2 of start, end, periods')

pandas/tseries/tests/test_period.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from pandas import Series, TimeSeries, DataFrame
2828
from pandas.util.testing import assert_series_equal, assert_almost_equal
2929
import pandas.util.testing as tm
30+
from pandas.util import py3compat
3031
from numpy.testing import assert_array_equal
3132

3233

@@ -1990,7 +1991,30 @@ def test_map(self):
19901991

19911992
result = index.map(lambda x: x.ordinal)
19921993
exp = [x.ordinal for x in index]
1993-
self.assert_(np.array_equal(result, exp))
1994+
assert_array_equal(result, exp)
1995+
1996+
def test_map_with_string_constructor(self):
1997+
raw = [2005, 2007, 2009]
1998+
index = PeriodIndex(raw, freq='A')
1999+
types = str,
2000+
if not py3compat.PY3:
2001+
types += unicode,
2002+
2003+
for t in types:
2004+
expected = np.array(map(t, raw), dtype=object)
2005+
res = index.map(t)
2006+
2007+
# should return an array
2008+
self.assert_(isinstance(res, np.ndarray))
2009+
2010+
# preserve element types
2011+
self.assert_(all(isinstance(resi, t) for resi in res))
2012+
2013+
# dtype should be object
2014+
self.assertEqual(res.dtype, np.dtype('object').type)
2015+
2016+
# lastly, values should compare equal
2017+
assert_array_equal(res, expected)
19942018

19952019
def test_convert_array_of_periods(self):
19962020
rng = period_range('1/1/2000', periods=20, freq='D')

0 commit comments

Comments
 (0)