Skip to content

Commit 63bbbde

Browse files
author
tp
committed
Added repr string for Grouper and TimeGrouper
1 parent c176a3c commit 63bbbde

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed

pandas/core/groupby.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ class Grouper(object):
233233
234234
>>> df.groupby(Grouper(level='date', freq='60s', axis=1))
235235
"""
236+
_attributes = collections.OrderedDict((('key', None), ('level', None),
237+
('freq', None), ('axis', 0),
238+
('sort', False)
239+
))
236240

237241
def __new__(cls, *args, **kwargs):
238242
if kwargs.get('freq') is not None:
@@ -333,6 +337,15 @@ def _set_grouper(self, obj, sort=False):
333337
def groups(self):
334338
return self.grouper.groups
335339

340+
def __repr__(self):
341+
defaults = self._attributes
342+
sd = self.__dict__
343+
attrs = collections.OrderedDict((k, sd[k]) for k, v in defaults.items()
344+
if k in sd and sd[k] != v)
345+
attrs = ", ".join("{}={!r}".format(k, v) for k, v in attrs.items())
346+
cls_name = self.__class__.__name__
347+
return "{}({})".format(cls_name, attrs)
348+
336349

337350
class GroupByPlot(PandasObject):
338351
"""

pandas/core/resample.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from datetime import timedelta
2+
import collections
23
import numpy as np
34
import warnings
45
import copy
@@ -1025,14 +1026,24 @@ class TimeGrouper(Grouper):
10251026
Use begin, end, nperiods to generate intervals that cannot be derived
10261027
directly from the associated object
10271028
"""
1029+
# _attributes is used in __repr__below
1030+
_attributes = Grouper._attributes.copy()
1031+
_attributes.update((('freq', 'Min'), ('closed', None), ('label', None),
1032+
('how', 'mean'), ('nperiods', None), ('axis', 0),
1033+
('fill_method', None), ('limit', None),
1034+
('loffset', None), ('kind', None),
1035+
('convention', None), ('base', 0),
1036+
('convention', 'e'), ('sort', True),
1037+
))
1038+
_end_types = {'M', 'A', 'Q', 'BM', 'BA', 'BQ', 'W'}
10281039

10291040
def __init__(self, freq='Min', closed=None, label=None, how='mean',
10301041
nperiods=None, axis=0,
10311042
fill_method=None, limit=None, loffset=None, kind=None,
10321043
convention=None, base=0, **kwargs):
10331044
freq = to_offset(freq)
10341045

1035-
end_types = set(['M', 'A', 'Q', 'BM', 'BA', 'BQ', 'W'])
1046+
end_types = self._end_types
10361047
rule = freq.rule_code
10371048
if (rule in end_types or
10381049
('-' in rule and rule[:rule.find('-')] in end_types)):
@@ -1047,6 +1058,7 @@ def __init__(self, freq='Min', closed=None, label=None, how='mean',
10471058
label = 'left'
10481059

10491060
self.closed = closed
1061+
self.freq = freq
10501062
self.label = label
10511063
self.nperiods = nperiods
10521064
self.kind = kind
@@ -1290,6 +1302,25 @@ def _get_period_bins(self, ax):
12901302

12911303
return binner, bins, labels
12921304

1305+
def __repr__(self):
1306+
defaults = self._attributes.copy()
1307+
end_types = self._end_types
1308+
rule = self.freq.rule_code
1309+
if (rule in end_types or
1310+
('-' in rule and rule[:rule.find('-')] in end_types)):
1311+
defaults.update(closed='right', label='right')
1312+
else:
1313+
defaults.update(closed='left', label='left')
1314+
1315+
sd = self.__dict__
1316+
attrs = collections.OrderedDict((k, sd[k]) for k, v in defaults.items()
1317+
if k in sd and sd[k] != v)
1318+
if 'freq' in attrs:
1319+
attrs['freq'] = attrs['freq'].freqstr
1320+
attrs = ", ".join("{}={!r}".format(k, v) for k, v in attrs.items())
1321+
cls_name = self.__class__.__name__
1322+
return "{}({})".format(cls_name, attrs)
1323+
12931324

12941325
def _take_new_index(obj, indexer, new_index, axis=0):
12951326
from pandas.core.api import Series, DataFrame

pandas/tests/test_resample.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3177,6 +3177,14 @@ def setup_method(self, method):
31773177
self.ts = Series(np.random.randn(1000),
31783178
index=date_range('1/1/2000', periods=1000))
31793179

3180+
def test_timegrouper_repr(self):
3181+
# Added in GH17727
3182+
result = repr(TimeGrouper(key='key', freq='50Min', label='right'))
3183+
cls_name_result, attrib_result = result.split('(')
3184+
attrib_result = set(attrib_result.rstrip(')').split(', '))
3185+
assert cls_name_result == 'TimeGrouper'
3186+
assert attrib_result == {"key='key'", "freq='50T'", "label='right'"}
3187+
31803188
def test_apply(self):
31813189
with tm.assert_produces_warning(FutureWarning,
31823190
check_stacklevel=False):

0 commit comments

Comments
 (0)