From 25ba926f7424b1c39f0f5922c308d0115386c1d9 Mon Sep 17 00:00:00 2001 From: Chris Zimmerman Date: Sun, 8 Sep 2019 22:25:53 -0500 Subject: [PATCH 1/3] GH28337: Period index doesn't handle reindexing with a non-period index --- doc/source/whatsnew/v1.0.0.rst | 2 +- pandas/core/indexes/period.py | 5 +++- pandas/tests/indexes/period/test_period.py | 29 ++++++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index e1fe2f7fe77e2..fd4b592d8414b 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -214,7 +214,7 @@ Other - Trying to set the ``display.precision``, ``display.max_rows`` or ``display.max_columns`` using :meth:`set_option` to anything but a ``None`` or a positive int will raise a ``ValueError`` (:issue:`23348`) - Using :meth:`DataFrame.replace` with overlapping keys in a nested dictionary will no longer raise, now matching the behavior of a flat dictionary (:issue:`27660`) - :meth:`DataFrame.to_csv` and :meth:`Series.to_csv` now support dicts as ``compression`` argument with key ``'method'`` being the compression method and others as additional compression options when the compression method is ``'zip'``. (:issue:`26023`) - +- Reindexing a `PeriodIndex` with an index of dtype `Object` no longer uses the `PeriodIndex`'s `_int64index` .. _whatsnew_1000.contributors: diff --git a/pandas/core/indexes/period.py b/pandas/core/indexes/period.py index f7bf77928bdc7..ee85b0fb91acb 100644 --- a/pandas/core/indexes/period.py +++ b/pandas/core/indexes/period.py @@ -651,10 +651,13 @@ def get_indexer(self, target, method=None, limit=None, tolerance=None): if isinstance(target, PeriodIndex): target = target.asi8 + self_index = self._int64index + else: + self_index = self if tolerance is not None: tolerance = self._convert_tolerance(tolerance, target) - return Index.get_indexer(self._int64index, target, method, limit, tolerance) + return Index.get_indexer(self_index, target, method, limit, tolerance) @Appender(_index_shared_docs["get_indexer_non_unique"] % _index_doc_kwargs) def get_indexer_non_unique(self, target): diff --git a/pandas/tests/indexes/period/test_period.py b/pandas/tests/indexes/period/test_period.py index 8b3b66bd1ee6b..ee37be7ab4c14 100644 --- a/pandas/tests/indexes/period/test_period.py +++ b/pandas/tests/indexes/period/test_period.py @@ -354,6 +354,35 @@ def test_period_set_index_reindex(self): df = df.set_index(idx2) tm.assert_index_equal(df.index, idx2) + @pytest.mark.parametrize( + "p_values, o_values, values, expected_values", + [ + ( + [Period("2019Q1", "Q-DEC"), Period("2019Q2", "Q-DEC")], + [Period("2019Q1", "Q-DEC"), Period("2019Q2", "Q-DEC"), "All"], + [1.0, 1.0], + [1.0, 1.0, np.nan], + ), + ( + [Period("2019Q1", "Q-DEC"), Period("2019Q2", "Q-DEC")], + [Period("2019Q1", "Q-DEC"), Period("2019Q2", "Q-DEC")], + [1.0, 1.0], + [1.0, 1.0], + ), + ], + ) + def test_period_reindex_with_object( + self, p_values, o_values, values, expected_values + ): + # GH 28337 + period_index = PeriodIndex(p_values) + object_index = Index(o_values) + + s = pd.Series(values, index=period_index) + result = s.reindex(object_index) + expected = pd.Series(expected_values, index=object_index) + tm.assert_series_equal(result, expected) + def test_factorize(self): idx1 = PeriodIndex( ["2014-01", "2014-01", "2014-02", "2014-02", "2014-03", "2014-03"], freq="M" From 2bc9762e07f979cff8cd4297bbaa4bf2051f6819 Mon Sep 17 00:00:00 2001 From: Chris Zimmerman Date: Mon, 9 Sep 2019 08:44:10 -0500 Subject: [PATCH 2/3] Added test for pivoting with a PeriodIndex, updated whatsnew --- doc/source/whatsnew/v1.0.0.rst | 4 ++-- pandas/tests/reshape/test_pivot.py | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index fd4b592d8414b..e6272b2a97dc1 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -145,7 +145,7 @@ Indexing ^^^^^^^^ - Bug in assignment using a reverse slicer (:issue:`26939`) -- +- Bug in reindexing a :meth:`PeriodIndex` with another type of index that contained a `Period` (:issue:`28323`) (:issue:`28337`) Missing ^^^^^^^ @@ -214,7 +214,7 @@ Other - Trying to set the ``display.precision``, ``display.max_rows`` or ``display.max_columns`` using :meth:`set_option` to anything but a ``None`` or a positive int will raise a ``ValueError`` (:issue:`23348`) - Using :meth:`DataFrame.replace` with overlapping keys in a nested dictionary will no longer raise, now matching the behavior of a flat dictionary (:issue:`27660`) - :meth:`DataFrame.to_csv` and :meth:`Series.to_csv` now support dicts as ``compression`` argument with key ``'method'`` being the compression method and others as additional compression options when the compression method is ``'zip'``. (:issue:`26023`) -- Reindexing a `PeriodIndex` with an index of dtype `Object` no longer uses the `PeriodIndex`'s `_int64index` +- .. _whatsnew_1000.contributors: diff --git a/pandas/tests/reshape/test_pivot.py b/pandas/tests/reshape/test_pivot.py index 03b15d2df1a26..d5ff8859ea38c 100644 --- a/pandas/tests/reshape/test_pivot.py +++ b/pandas/tests/reshape/test_pivot.py @@ -677,6 +677,31 @@ def test_pivot_periods(self, method): pv = pd.pivot(df, index="p1", columns="p2", values="data1") tm.assert_frame_equal(pv, expected) + def test_pivot_periods_with_margins(self): + df = DataFrame( + { + "a": [1, 1, 2, 2], + "b": [ + pd.Period("2019Q1"), + pd.Period("2019Q2"), + pd.Period("2019Q1"), + pd.Period("2019Q2"), + ], + "x": 1.0, + } + ) + + expected = DataFrame( + data=1.0, + index=pd.Index([1, 2, "All"], name="a"), + columns=pd.Index( + [pd.Period("2019Q1"), pd.Period("2019Q2"), "All"], name="b" + ), + ) + + result = df.pivot_table(index="a", columns="b", values="x", margins=True) + tm.assert_frame_equal(expected, result) + @pytest.mark.parametrize( "values", [ From 9fbaf86056f9ae314d807b0bcd13778d1cdc6c7a Mon Sep 17 00:00:00 2001 From: Chris Zimmerman Date: Mon, 9 Sep 2019 20:54:11 -0500 Subject: [PATCH 3/3] Reference issue in period pivot test --- pandas/tests/reshape/test_pivot.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tests/reshape/test_pivot.py b/pandas/tests/reshape/test_pivot.py index d5ff8859ea38c..582084e3bfb5a 100644 --- a/pandas/tests/reshape/test_pivot.py +++ b/pandas/tests/reshape/test_pivot.py @@ -678,6 +678,7 @@ def test_pivot_periods(self, method): tm.assert_frame_equal(pv, expected) def test_pivot_periods_with_margins(self): + # GH 28323 df = DataFrame( { "a": [1, 1, 2, 2],