Skip to content

Commit 54d7503

Browse files
committed
BUG: groupby agg over PeriodIndex unboxes to ordinals #2569
1 parent 22e8bc7 commit 54d7503

File tree

4 files changed

+27
-8
lines changed

4 files changed

+27
-8
lines changed

pandas/core/algorithms.py

+8-5
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,14 @@ def factorize(values, sort=False, order=None, na_sentinel=-1):
115115
Returns
116116
-------
117117
"""
118-
values = np.asarray(values)
119-
is_datetime = com.is_datetime64_dtype(values)
120-
(hash_klass, vec_klass), values = _get_data_algo(values, _hashtables)
118+
from pandas.tseries.period import PeriodIndex
119+
vals = np.asarray(values)
120+
is_datetime = com.is_datetime64_dtype(vals)
121+
(hash_klass, vec_klass), vals = _get_data_algo(vals, _hashtables)
121122

122-
table = hash_klass(len(values))
123+
table = hash_klass(len(vals))
123124
uniques = vec_klass()
124-
labels = table.get_labels(values, uniques, 0, na_sentinel)
125+
labels = table.get_labels(vals, uniques, 0, na_sentinel)
125126

126127
labels = com._ensure_platform_int(labels)
127128

@@ -140,6 +141,8 @@ def factorize(values, sort=False, order=None, na_sentinel=-1):
140141

141142
if is_datetime:
142143
uniques = uniques.view('M8[ns]')
144+
if isinstance(values, PeriodIndex):
145+
uniques = PeriodIndex(ordinal=uniques, freq=values.freq)
143146

144147
return labels, uniques
145148

pandas/core/index.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class Index(np.ndarray):
8686
_engine_type = _index.ObjectEngine
8787

8888
def __new__(cls, data, dtype=None, copy=False, name=None):
89+
from pandas.tseries.period import PeriodIndex
8990
if isinstance(data, np.ndarray):
9091
if issubclass(data.dtype.type, np.datetime64):
9192
from pandas.tseries.index import DatetimeIndex
@@ -100,6 +101,8 @@ def __new__(cls, data, dtype=None, copy=False, name=None):
100101
data = np.array(data, dtype=dtype, copy=copy)
101102
except TypeError:
102103
pass
104+
elif isinstance(data, PeriodIndex):
105+
return PeriodIndex(data, copy=copy, name=name)
103106

104107
if issubclass(data.dtype.type, np.integer):
105108
return Int64Index(data, copy=copy, name=name)
@@ -122,9 +125,8 @@ def __new__(cls, data, dtype=None, copy=False, name=None):
122125
from pandas.tseries.index import DatetimeIndex
123126
return DatetimeIndex(subarr, copy=copy, name=name)
124127

125-
if lib.is_period_array(subarr):
126-
from pandas.tseries.period import PeriodIndex
127-
return PeriodIndex(subarr, name=name)
128+
if lib.is_period_array(subarr):
129+
return PeriodIndex(subarr, name=name)
128130

129131
subarr = subarr.view(cls)
130132
subarr.name = name

pandas/tests/test_groupby.py

+7
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,13 @@ def test_agg_datetimes_mixed(self):
224224

225225
assert(len(gb1) == len(gb2))
226226

227+
def test_agg_period_index(self):
228+
from pandas import period_range, PeriodIndex
229+
prng = period_range('2012-1-1', freq='M', periods=3)
230+
df = DataFrame(np.random.randn(3, 2), index=prng)
231+
rs = df.groupby(level=0).sum()
232+
self.assert_(isinstance(rs.index, PeriodIndex))
233+
227234
def test_agg_must_agg(self):
228235
grouped = self.df.groupby('A')['C']
229236
self.assertRaises(Exception, grouped.agg, lambda x: x.describe())

pandas/tests/test_index.py

+7
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ def test_constructor_corner(self):
8686
# corner case
8787
self.assertRaises(Exception, Index, 0)
8888

89+
def test_index_ctor_infer_periodindex(self):
90+
from pandas import period_range, PeriodIndex
91+
xp = period_range('2012-1-1', freq='M', periods=3)
92+
rs = Index(xp)
93+
assert_array_equal(rs, xp)
94+
self.assert_(isinstance(rs, PeriodIndex))
95+
8996
def test_copy(self):
9097
i = Index([], name='Foo')
9198
i_copy = i.copy()

0 commit comments

Comments
 (0)