Skip to content

Commit 0db1ef2

Browse files
committed
Merge pull request #7606 from sinhrks/freqstr
BUG: DTI.freqstr raises AttributeError when freq is None
2 parents 181431f + 4b27023 commit 0db1ef2

File tree

5 files changed

+41
-19
lines changed

5 files changed

+41
-19
lines changed

doc/source/v0.14.1.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ Bug Fixes
258258
- Bug in ``Index.astype(float)`` where it would return an ``object`` dtype
259259
``Index`` (:issue:`7464`).
260260
- Bug in ``DataFrame.reset_index`` loses ``tz`` (:issue:`3950`)
261-
261+
- Bug in ``DatetimeIndex.freqstr`` raises ``AttributeError`` when ``freq`` is ``None`` (:issue:`7606`)
262262

263263
- Bug in non-monotonic ``Index.union`` may preserve ``name`` incorrectly (:issue:`7458`)
264264
- Bug in ``DatetimeIndex.intersection`` doesn't preserve timezone (:issue:`4690`)

pandas/core/frame.py

-4
Original file line numberDiff line numberDiff line change
@@ -4311,12 +4311,8 @@ def to_period(self, freq=None, axis=0, copy=True):
43114311

43124312
axis = self._get_axis_number(axis)
43134313
if axis == 0:
4314-
if freq is None:
4315-
freq = self.index.freqstr or self.index.inferred_freq
43164314
new_data.set_axis(1, self.index.to_period(freq=freq))
43174315
elif axis == 1:
4318-
if freq is None:
4319-
freq = self.columns.freqstr or self.columns.inferred_freq
43204316
new_data.set_axis(0, self.columns.to_period(freq=freq))
43214317
else: # pragma: no cover
43224318
raise AssertionError('Axis must be 0 or 1. Got %s' % str(axis))

pandas/core/series.py

-2
Original file line numberDiff line numberDiff line change
@@ -2374,8 +2374,6 @@ def to_period(self, freq=None, copy=True):
23742374
if copy:
23752375
new_values = new_values.copy()
23762376

2377-
if freq is None:
2378-
freq = self.index.freqstr or self.index.inferred_freq
23792377
new_index = self.index.to_period(freq=freq)
23802378
return self._constructor(new_values,
23812379
index=new_index).__finalize__(self)

pandas/tseries/index.py

+11-11
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ def f(self):
4848
'is_quarter_start', 'is_quarter_end',
4949
'is_year_start', 'is_year_end']:
5050
month_kw = self.freq.kwds.get('startingMonth', self.freq.kwds.get('month', 12)) if self.freq else 12
51-
freqstr = self.freqstr if self.freq else None
52-
return tslib.get_start_end_field(values, field, freqstr, month_kw)
51+
return tslib.get_start_end_field(values, field, self.freqstr, month_kw)
5352
else:
5453
return tslib.get_date_field(values, field)
5554
f.__name__ = name
@@ -573,10 +572,7 @@ def __unicode__(self):
573572

574573
values = self.values
575574

576-
freq = None
577-
if self.offset is not None:
578-
freq = self.offset.freqstr
579-
575+
freq = self.freqstr
580576
summary = str(self.__class__)
581577
if len(self) == 1:
582578
first = formatter(values[0], tz=self.tz)
@@ -794,12 +790,14 @@ def to_period(self, freq=None):
794790
"""
795791
from pandas.tseries.period import PeriodIndex
796792

797-
if self.freq is None and freq is None:
798-
msg = "You must pass a freq argument as current index has none."
799-
raise ValueError(msg)
800-
801793
if freq is None:
802-
freq = get_period_alias(self.freqstr)
794+
freq = self.freqstr or self.inferred_freq
795+
796+
if freq is None:
797+
msg = "You must pass a freq argument as current index has none."
798+
raise ValueError(msg)
799+
800+
freq = get_period_alias(freq)
803801

804802
return PeriodIndex(self.values, name=self.name, freq=freq, tz=self.tz)
805803

@@ -1440,6 +1438,8 @@ def inferred_freq(self):
14401438
@property
14411439
def freqstr(self):
14421440
""" return the frequency object as a string if its set, otherwise None """
1441+
if self.freq is None:
1442+
return None
14431443
return self.offset.freqstr
14441444

14451445
_year = _field_accessor('year', 'Y')

pandas/tseries/tests/test_timeseries.py

+29-1
Original file line numberDiff line numberDiff line change
@@ -1477,7 +1477,28 @@ def test_to_period(self):
14771477
assert_series_equal(pts, exp)
14781478

14791479
pts = ts.to_period('M')
1480+
exp.index = exp.index.asfreq('M')
14801481
self.assertTrue(pts.index.equals(exp.index.asfreq('M')))
1482+
assert_series_equal(pts, exp)
1483+
1484+
# GH 7606 without freq
1485+
idx = DatetimeIndex(['2011-01-01', '2011-01-02', '2011-01-03', '2011-01-04'])
1486+
exp_idx = pd.PeriodIndex(['2011-01-01', '2011-01-02', '2011-01-03',
1487+
'2011-01-04'], freq='D')
1488+
1489+
s = Series(np.random.randn(4), index=idx)
1490+
expected = s.copy()
1491+
expected.index = exp_idx
1492+
assert_series_equal(s.to_period(), expected)
1493+
1494+
df = DataFrame(np.random.randn(4, 4), index=idx, columns=idx)
1495+
expected = df.copy()
1496+
expected.index = exp_idx
1497+
assert_frame_equal(df.to_period(), expected)
1498+
1499+
expected = df.copy()
1500+
expected.columns = exp_idx
1501+
assert_frame_equal(df.to_period(axis=1), expected)
14811502

14821503
def create_dt64_based_index(self):
14831504
data = [Timestamp('2007-01-01 10:11:12.123456Z'),
@@ -2102,7 +2123,14 @@ def test_to_period_nofreq(self):
21022123

21032124
idx = DatetimeIndex(['2000-01-01', '2000-01-02', '2000-01-03'],
21042125
freq='infer')
2105-
idx.to_period()
2126+
self.assertEqual(idx.freqstr, 'D')
2127+
expected = pd.PeriodIndex(['2000-01-01', '2000-01-02', '2000-01-03'], freq='D')
2128+
self.assertTrue(idx.to_period().equals(expected))
2129+
2130+
# GH 7606
2131+
idx = DatetimeIndex(['2000-01-01', '2000-01-02', '2000-01-03'])
2132+
self.assertEqual(idx.freqstr, None)
2133+
self.assertTrue(idx.to_period().equals(expected))
21062134

21072135
def test_000constructor_resolution(self):
21082136
# 2252

0 commit comments

Comments
 (0)