From 9dd77d5538d58fa92df1ee485ef1b1af71186874 Mon Sep 17 00:00:00 2001 From: sinhrks Date: Sat, 20 Dec 2014 14:51:42 +0900 Subject: [PATCH] API: Datetime-like indexes `summary` should output the same format --- doc/source/whatsnew/v0.16.0.txt | 4 ++ pandas/tseries/base.py | 27 +++++++ pandas/tseries/index.py | 23 ------ pandas/tseries/tdi.py | 24 ------- pandas/tseries/tests/test_base.py | 96 +++++++++++++++++++++++-- pandas/tseries/tests/test_timedeltas.py | 2 +- 6 files changed, 124 insertions(+), 52 deletions(-) diff --git a/doc/source/whatsnew/v0.16.0.txt b/doc/source/whatsnew/v0.16.0.txt index 9b8382bd3f4c4..ee5ed49dfb5d1 100644 --- a/doc/source/whatsnew/v0.16.0.txt +++ b/doc/source/whatsnew/v0.16.0.txt @@ -29,6 +29,10 @@ Backwards incompatible API changes - ``Index.duplicated`` now returns `np.array(dtype=bool)` rather than `Index(dtype=object)` containing `bool` values. (:issue:`8875`) +- ``DatetimeIndex``, ``PeriodIndex`` and ``TimedeltaIndex.summary`` now output the same format. (:issue:`9116`) +- ``TimedeltaIndex.freqstr`` now output the same string format as ``DatetimeIndex``. (:issue:`9116`) + + Deprecations ~~~~~~~~~~~~ diff --git a/pandas/tseries/base.py b/pandas/tseries/base.py index b223d2bfd9ebc..266e69cf3484b 100644 --- a/pandas/tseries/base.py +++ b/pandas/tseries/base.py @@ -69,6 +69,13 @@ def __contains__(self, key): except (KeyError, TypeError): return False + @property + def freqstr(self): + """ return the frequency object as a string if its set, otherwise None """ + if self.freq is None: + return None + return self.freq.freqstr + @cache_readonly def inferred_freq(self): try: @@ -459,3 +466,23 @@ def repeat(self, repeats, axis=None): """ return self._simple_new(self.values.repeat(repeats), name=self.name) + + def summary(self, name=None): + """ + return a summarized representation + """ + formatter = self._formatter_func + if len(self) > 0: + index_summary = ', %s to %s' % (formatter(self[0]), + formatter(self[-1])) + else: + index_summary = '' + + if name is None: + name = type(self).__name__ + result = '%s: %s entries%s' % (com.pprint_thing(name), + len(self), index_summary) + if self.freq: + result += '\nFreq: %s' % self.freqstr + + return result diff --git a/pandas/tseries/index.py b/pandas/tseries/index.py index 5e621761d63b6..65414fe39d18c 100644 --- a/pandas/tseries/index.py +++ b/pandas/tseries/index.py @@ -682,22 +682,6 @@ def _format_native_types(self, na_rep=u('NaT'), def to_datetime(self, dayfirst=False): return self.copy() - def summary(self, name=None): - if len(self) > 0: - index_summary = ', %s to %s' % (com.pprint_thing(self[0]), - com.pprint_thing(self[-1])) - else: - index_summary = '' - - if name is None: - name = type(self).__name__ - result = '%s: %s entries%s' % (com.pprint_thing(name), - len(self), index_summary) - if self.freq: - result += '\nFreq: %s' % self.freqstr - - return result - def _format_footer(self): tagline = 'Length: %d, Freq: %s, Timezone: %s' return tagline % (len(self), self.freqstr, self.tz) @@ -1392,13 +1376,6 @@ def _set_freq(self, value): self.offset = value freq = property(fget=_get_freq, fset=_set_freq, doc="get/set the frequncy of the Index") - @property - def freqstr(self): - """ return the frequency object as a string if its set, otherwise None """ - if self.freq is None: - return None - return self.offset.freqstr - year = _field_accessor('year', 'Y', "The year of the datetime") month = _field_accessor('month', 'M', "The month as January=1, December=12") day = _field_accessor('day', 'D', "The days of the datetime") diff --git a/pandas/tseries/tdi.py b/pandas/tseries/tdi.py index 5a946acac2baa..097ccef9e462b 100644 --- a/pandas/tseries/tdi.py +++ b/pandas/tseries/tdi.py @@ -410,23 +410,6 @@ def f(x): result = result.astype('int64') return result - def summary(self, name=None): - formatter = self._formatter_func - if len(self) > 0: - index_summary = ', %s to %s' % (formatter(self[0]), - formatter(self[-1])) - else: - index_summary = '' - - if name is None: - name = type(self).__name__ - result = '%s: %s entries%s' % (com.pprint_thing(name), - len(self), index_summary) - if self.freq: - result += '\nFreq: %s' % self.freqstr - - return result - def to_pytimedelta(self): """ Return TimedeltaIndex as object ndarray of datetime.timedelta objects @@ -796,13 +779,6 @@ def __getitem__(self, key): return self._simple_new(result, self.name) - @property - def freqstr(self): - """ return the frequency object as a string if its set, otherwise None """ - if self.freq is None: - return None - return self.freq - def searchsorted(self, key, side='left'): if isinstance(key, (np.ndarray, Index)): key = np.array(key, dtype=_TD_DTYPE, copy=False) diff --git a/pandas/tseries/tests/test_base.py b/pandas/tseries/tests/test_base.py index d3393feb2ca33..1ecd723ed8d56 100644 --- a/pandas/tseries/tests/test_base.py +++ b/pandas/tseries/tests/test_base.py @@ -143,6 +143,34 @@ def test_representation(self): result = getattr(idx, func)() self.assertEqual(result, expected) + def test_summary(self): + # GH9116 + idx1 = DatetimeIndex([], freq='D') + idx2 = DatetimeIndex(['2011-01-01'], freq='D') + idx3 = DatetimeIndex(['2011-01-01', '2011-01-02'], freq='D') + idx4 = DatetimeIndex(['2011-01-01', '2011-01-02', '2011-01-03'], freq='D') + idx5 = DatetimeIndex(['2011-01-01 09:00', '2011-01-01 10:00', '2011-01-01 11:00'], + freq='H', tz='Asia/Tokyo') + idx6 = DatetimeIndex(['2011-01-01 09:00', '2011-01-01 10:00', pd.NaT], + tz='US/Eastern') + + exp1 = """DatetimeIndex: 0 entries +Freq: D""" + exp2 = """DatetimeIndex: 1 entries, 2011-01-01 to 2011-01-01 +Freq: D""" + exp3 = """DatetimeIndex: 2 entries, 2011-01-01 to 2011-01-02 +Freq: D""" + exp4 = """DatetimeIndex: 3 entries, 2011-01-01 to 2011-01-03 +Freq: D""" + exp5 = """DatetimeIndex: 3 entries, 2011-01-01 09:00:00+09:00 to 2011-01-01 11:00:00+09:00 +Freq: H""" + exp6 = """DatetimeIndex: 3 entries, 2011-01-01 09:00:00-05:00 to NaT""" + + for idx, expected in zip([idx1, idx2, idx3, idx4, idx5, idx6], + [exp1, exp2, exp3, exp4, exp5, exp6]): + result = idx.summary() + self.assertEqual(result, expected) + def test_resolution(self): for freq, expected in zip(['A', 'Q', 'M', 'D', 'H', 'T', 'S', 'L', 'U'], ['day', 'day', 'day', 'day', @@ -336,16 +364,16 @@ def test_representation(self): exp1 = """ -Length: 0, Freq: """ +Length: 0, Freq: D""" exp2 = """ ['1 days'] -Length: 1, Freq: """ +Length: 1, Freq: D""" exp3 = """ ['1 days', '2 days'] -Length: 2, Freq: """ +Length: 2, Freq: D""" exp4 = """ ['1 days', ..., '3 days'] -Length: 3, Freq: """ +Length: 3, Freq: D""" exp5 = """ ['1 days 00:00:01', ..., '3 days 00:00:00'] Length: 3, Freq: None""" @@ -356,6 +384,29 @@ def test_representation(self): result = getattr(idx, func)() self.assertEqual(result, expected) + def test_summary(self): + # GH9116 + idx1 = TimedeltaIndex([], freq='D') + idx2 = TimedeltaIndex(['1 days'], freq='D') + idx3 = TimedeltaIndex(['1 days', '2 days'], freq='D') + idx4 = TimedeltaIndex(['1 days', '2 days', '3 days'], freq='D') + idx5 = TimedeltaIndex(['1 days 00:00:01', '2 days', '3 days']) + + exp1 = """TimedeltaIndex: 0 entries +Freq: D""" + exp2 = """TimedeltaIndex: 1 entries, '1 days' to '1 days' +Freq: D""" + exp3 = """TimedeltaIndex: 2 entries, '1 days' to '2 days' +Freq: D""" + exp4 = """TimedeltaIndex: 3 entries, '1 days' to '3 days' +Freq: D""" + exp5 = """TimedeltaIndex: 3 entries, '1 days 00:00:01' to '3 days 00:00:00'""" + + for idx, expected in zip([idx1, idx2, idx3, idx4, idx5], + [exp1, exp2, exp3, exp4, exp5]): + result = idx.summary() + self.assertEqual(result, expected) + def test_add_iadd(self): # only test adding/sub offsets as + is now numeric @@ -755,6 +806,43 @@ def test_representation(self): result = getattr(idx, func)() self.assertEqual(result, expected) + def test_summary(self): + # GH9116 + idx1 = PeriodIndex([], freq='D') + idx2 = PeriodIndex(['2011-01-01'], freq='D') + idx3 = PeriodIndex(['2011-01-01', '2011-01-02'], freq='D') + idx4 = PeriodIndex(['2011-01-01', '2011-01-02', '2011-01-03'], freq='D') + idx5 = PeriodIndex(['2011', '2012', '2013'], freq='A') + idx6 = PeriodIndex(['2011-01-01 09:00', '2012-02-01 10:00', 'NaT'], freq='H') + + idx7 = pd.period_range('2013Q1', periods=1, freq="Q") + idx8 = pd.period_range('2013Q1', periods=2, freq="Q") + idx9 = pd.period_range('2013Q1', periods=3, freq="Q") + + exp1 = """PeriodIndex: 0 entries +Freq: D""" + exp2 = """PeriodIndex: 1 entries, 2011-01-01 to 2011-01-01 +Freq: D""" + exp3 = """PeriodIndex: 2 entries, 2011-01-01 to 2011-01-02 +Freq: D""" + exp4 = """PeriodIndex: 3 entries, 2011-01-01 to 2011-01-03 +Freq: D""" + exp5 = """PeriodIndex: 3 entries, 2011 to 2013 +Freq: A-DEC""" + exp6 = """PeriodIndex: 3 entries, 2011-01-01 09:00 to NaT +Freq: H""" + exp7 = """PeriodIndex: 1 entries, 2013Q1 to 2013Q1 +Freq: Q-DEC""" + exp8 = """PeriodIndex: 2 entries, 2013Q1 to 2013Q2 +Freq: Q-DEC""" + exp9 = """PeriodIndex: 3 entries, 2013Q1 to 2013Q3 +Freq: Q-DEC""" + + for idx, expected in zip([idx1, idx2, idx3, idx4, idx5, idx6, idx7, idx8, idx9], + [exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8, exp9]): + result = idx.summary() + self.assertEqual(result, expected) + def test_resolution(self): for freq, expected in zip(['A', 'Q', 'M', 'D', 'H', 'T', 'S', 'L', 'U'], ['day', 'day', 'day', 'day', diff --git a/pandas/tseries/tests/test_timedeltas.py b/pandas/tseries/tests/test_timedeltas.py index de23ddcc397d9..b6c5327357590 100644 --- a/pandas/tseries/tests/test_timedeltas.py +++ b/pandas/tseries/tests/test_timedeltas.py @@ -540,7 +540,7 @@ def conv(v): expected = np.array([0, 500000000, 800000000, 1200000000], dtype='timedelta64[ns]') result = to_timedelta([0., 0.5, 0.8, 1.2], unit='s', box=False) tm.assert_numpy_array_equal(expected, result) - + def testit(unit, transform): # array