diff --git a/doc/source/v0.14.1.txt b/doc/source/v0.14.1.txt index 3160b35386fa2..a46718c8e88f3 100644 --- a/doc/source/v0.14.1.txt +++ b/doc/source/v0.14.1.txt @@ -258,7 +258,7 @@ Bug Fixes - Bug in ``Index.astype(float)`` where it would return an ``object`` dtype ``Index`` (:issue:`7464`). - Bug in ``DataFrame.reset_index`` loses ``tz`` (:issue:`3950`) - +- Bug in ``DatetimeIndex.freqstr`` raises ``AttributeError`` when ``freq`` is ``None`` (:issue:`7606`) - Bug in non-monotonic ``Index.union`` may preserve ``name`` incorrectly (:issue:`7458`) - Bug in ``DatetimeIndex.intersection`` doesn't preserve timezone (:issue:`4690`) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index b4e69e2056507..e7678e31d50ab 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4311,12 +4311,8 @@ def to_period(self, freq=None, axis=0, copy=True): axis = self._get_axis_number(axis) if axis == 0: - if freq is None: - freq = self.index.freqstr or self.index.inferred_freq new_data.set_axis(1, self.index.to_period(freq=freq)) elif axis == 1: - if freq is None: - freq = self.columns.freqstr or self.columns.inferred_freq new_data.set_axis(0, self.columns.to_period(freq=freq)) else: # pragma: no cover raise AssertionError('Axis must be 0 or 1. Got %s' % str(axis)) diff --git a/pandas/core/series.py b/pandas/core/series.py index 78b049f4bf8d5..a484efe75e284 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -2374,8 +2374,6 @@ def to_period(self, freq=None, copy=True): if copy: new_values = new_values.copy() - if freq is None: - freq = self.index.freqstr or self.index.inferred_freq new_index = self.index.to_period(freq=freq) return self._constructor(new_values, index=new_index).__finalize__(self) diff --git a/pandas/tseries/index.py b/pandas/tseries/index.py index ff585d80af830..e439d7d523bd3 100644 --- a/pandas/tseries/index.py +++ b/pandas/tseries/index.py @@ -48,8 +48,7 @@ def f(self): 'is_quarter_start', 'is_quarter_end', 'is_year_start', 'is_year_end']: month_kw = self.freq.kwds.get('startingMonth', self.freq.kwds.get('month', 12)) if self.freq else 12 - freqstr = self.freqstr if self.freq else None - return tslib.get_start_end_field(values, field, freqstr, month_kw) + return tslib.get_start_end_field(values, field, self.freqstr, month_kw) else: return tslib.get_date_field(values, field) f.__name__ = name @@ -573,10 +572,7 @@ def __unicode__(self): values = self.values - freq = None - if self.offset is not None: - freq = self.offset.freqstr - + freq = self.freqstr summary = str(self.__class__) if len(self) == 1: first = formatter(values[0], tz=self.tz) @@ -794,12 +790,14 @@ def to_period(self, freq=None): """ from pandas.tseries.period import PeriodIndex - if self.freq is None and freq is None: - msg = "You must pass a freq argument as current index has none." - raise ValueError(msg) - if freq is None: - freq = get_period_alias(self.freqstr) + freq = self.freqstr or self.inferred_freq + + if freq is None: + msg = "You must pass a freq argument as current index has none." + raise ValueError(msg) + + freq = get_period_alias(freq) return PeriodIndex(self.values, name=self.name, freq=freq, tz=self.tz) @@ -1440,6 +1438,8 @@ def inferred_freq(self): @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') diff --git a/pandas/tseries/tests/test_timeseries.py b/pandas/tseries/tests/test_timeseries.py index 11161308be279..eb7ee6e87477c 100644 --- a/pandas/tseries/tests/test_timeseries.py +++ b/pandas/tseries/tests/test_timeseries.py @@ -1477,7 +1477,28 @@ def test_to_period(self): assert_series_equal(pts, exp) pts = ts.to_period('M') + exp.index = exp.index.asfreq('M') self.assertTrue(pts.index.equals(exp.index.asfreq('M'))) + assert_series_equal(pts, exp) + + # GH 7606 without freq + idx = DatetimeIndex(['2011-01-01', '2011-01-02', '2011-01-03', '2011-01-04']) + exp_idx = pd.PeriodIndex(['2011-01-01', '2011-01-02', '2011-01-03', + '2011-01-04'], freq='D') + + s = Series(np.random.randn(4), index=idx) + expected = s.copy() + expected.index = exp_idx + assert_series_equal(s.to_period(), expected) + + df = DataFrame(np.random.randn(4, 4), index=idx, columns=idx) + expected = df.copy() + expected.index = exp_idx + assert_frame_equal(df.to_period(), expected) + + expected = df.copy() + expected.columns = exp_idx + assert_frame_equal(df.to_period(axis=1), expected) def create_dt64_based_index(self): data = [Timestamp('2007-01-01 10:11:12.123456Z'), @@ -2102,7 +2123,14 @@ def test_to_period_nofreq(self): idx = DatetimeIndex(['2000-01-01', '2000-01-02', '2000-01-03'], freq='infer') - idx.to_period() + self.assertEqual(idx.freqstr, 'D') + expected = pd.PeriodIndex(['2000-01-01', '2000-01-02', '2000-01-03'], freq='D') + self.assertTrue(idx.to_period().equals(expected)) + + # GH 7606 + idx = DatetimeIndex(['2000-01-01', '2000-01-02', '2000-01-03']) + self.assertEqual(idx.freqstr, None) + self.assertTrue(idx.to_period().equals(expected)) def test_000constructor_resolution(self): # 2252