From c558aba332886527fcf78efa7cee1c0b0d310dc2 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Thu, 3 Jan 2019 15:51:15 -0600 Subject: [PATCH 1/3] Fixed PeriodIndex._shallow_copy for i8 Closes https://github.com/pandas-dev/pandas/issues/24391 --- pandas/core/indexes/period.py | 8 ++------ pandas/tests/indexes/period/test_period.py | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/pandas/core/indexes/period.py b/pandas/core/indexes/period.py index b59c32bb8a9d4..5e4dd2998a3be 100644 --- a/pandas/core/indexes/period.py +++ b/pandas/core/indexes/period.py @@ -322,13 +322,9 @@ def _shallow_copy(self, values=None, **kwargs): # this quite a bit. values = period_array(values, freq=self.freq) - # I don't like overloading shallow_copy with freq changes. - # See if it's used anywhere outside of test_resample_empty_dataframe + # We don't allow changing `freq` in _shallow_copy. + validate_dtype_freq(self.dtype, kwargs.get('freq')) attributes = self._get_attributes_dict() - freq = kwargs.pop("freq", None) - if freq: - values = values.asfreq(freq) - attributes.pop("freq", None) attributes.update(kwargs) if not len(values) and 'dtype' not in kwargs: diff --git a/pandas/tests/indexes/period/test_period.py b/pandas/tests/indexes/period/test_period.py index 53f28612305c2..464ff7aa5d58d 100644 --- a/pandas/tests/indexes/period/test_period.py +++ b/pandas/tests/indexes/period/test_period.py @@ -1,6 +1,7 @@ import numpy as np import pytest +from pandas._libs.tslibs.period import IncompatibleFrequency import pandas.util._test_decorators as td import pandas as pd @@ -40,9 +41,7 @@ def test_where(self): @pytest.mark.parametrize('use_numpy', [True, False]) @pytest.mark.parametrize('index', [ pd.period_range('2000-01-01', periods=3, freq='D'), - pytest.param( - pd.period_range('2001-01-01', periods=3, freq='2D'), - marks=pytest.mark.xfail(reason='GH 24391')), + pd.period_range('2001-01-01', periods=3, freq='2D'), pd.PeriodIndex(['2001-01', 'NaT', '2003-01'], freq='M')]) def test_repeat_freqstr(self, index, use_numpy): # GH10183 @@ -117,6 +116,17 @@ def test_shallow_copy_empty(self): tm.assert_index_equal(result, expected) + def test_shallow_copy_i8(self): + # GH-24391 + pi = period_range("2018-01-01", periods=3, freq="2D") + result = pi._shallow_copy(pi.asi8, freq=pi.freq) + tm.assert_index_equal(result, pi) + + def test_shallow_copy_changing_freq_raises(self): + pi = period_range("2018-01-01", periods=3, freq="2D") + with pytest.raises(IncompatibleFrequency, match="are different"): + pi._shallow_copy(pi, freq="H") + def test_dtype_str(self): pi = pd.PeriodIndex([], freq='M') assert pi.dtype_str == 'period[M]' From 2b1bfeb844a17c8b1ee4fa3e9203645378ee52b3 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Fri, 4 Jan 2019 07:00:55 -0600 Subject: [PATCH 2/3] fixup --- pandas/core/resample.py | 2 +- pandas/tests/resample/test_base.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pandas/core/resample.py b/pandas/core/resample.py index ee9137c264edc..19c88079ebee2 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -404,7 +404,7 @@ def _wrap_result(self, result): if isinstance(result, ABCSeries) and result.empty: obj = self.obj - result.index = obj.index._shallow_copy(freq=to_offset(self.freq)) + result.index = obj.index.asfreq(self.freq) result.name = getattr(obj, 'name', None) return result diff --git a/pandas/tests/resample/test_base.py b/pandas/tests/resample/test_base.py index 31199dc01b659..de52f6af88e87 100644 --- a/pandas/tests/resample/test_base.py +++ b/pandas/tests/resample/test_base.py @@ -109,7 +109,10 @@ def test_resample_empty_series_all_ts(freq, empty_series, resample_method): result = getattr(s.resample(freq), resample_method)() expected = s.copy() - expected.index = s.index._shallow_copy(freq=freq) + if isinstance(s.index, PeriodIndex): + expected.index = s.index.asfreq(freq=freq) + else: + expected.index = s.index._shallow_copy(freq=freq) assert_index_equal(result.index, expected.index) assert result.index.freq == expected.index.freq assert_series_equal(result, expected, check_dtype=False) @@ -127,7 +130,7 @@ def test_resample_empty_dataframe_all_ts(empty_frame, freq, resample_method): # GH14962 expected = Series([]) - expected.index = df.index._shallow_copy(freq=freq) + expected.index = df.index.asfreq(freq=freq) assert_index_equal(result.index, expected.index) assert result.index.freq == expected.index.freq assert_almost_equal(result, expected, check_dtype=False) From 776aa90010b568ff753905b92f0e648d6fcdff7f Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Fri, 4 Jan 2019 07:03:34 -0600 Subject: [PATCH 3/3] fixup --- pandas/core/resample.py | 5 ++++- pandas/tests/resample/test_base.py | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pandas/core/resample.py b/pandas/core/resample.py index 19c88079ebee2..25604b29f22f6 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -404,7 +404,10 @@ def _wrap_result(self, result): if isinstance(result, ABCSeries) and result.empty: obj = self.obj - result.index = obj.index.asfreq(self.freq) + if isinstance(obj.index, PeriodIndex): + result.index = obj.index.asfreq(self.freq) + else: + result.index = obj.index._shallow_copy(freq=self.freq) result.name = getattr(obj, 'name', None) return result diff --git a/pandas/tests/resample/test_base.py b/pandas/tests/resample/test_base.py index 45ee16183ec54..911cd990ab881 100644 --- a/pandas/tests/resample/test_base.py +++ b/pandas/tests/resample/test_base.py @@ -130,7 +130,10 @@ def test_resample_empty_dataframe_all_ts(empty_frame, freq, resample_method): # GH14962 expected = Series([]) - expected.index = df.index.asfreq(freq=freq) + if isinstance(df.index, PeriodIndex): + expected.index = df.index.asfreq(freq=freq) + else: + expected.index = df.index._shallow_copy(freq=freq) assert_index_equal(result.index, expected.index) assert result.index.freq == expected.index.freq assert_almost_equal(result, expected, check_dtype=False)