From fd2fa21360b7f2f5f27df7d89aeab5744f1174ed Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Sun, 5 Apr 2020 11:42:51 -0500 Subject: [PATCH 1/5] REGR: Fix construction of PeriodIndex from strings --- doc/source/whatsnew/v1.1.0.rst | 1 + pandas/core/arrays/period.py | 5 +++-- pandas/tests/arrays/test_datetimelike.py | 7 +++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index 8bff34dbdadad..5eb8191dc27e9 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -304,6 +304,7 @@ Datetimelike - :class:`Timestamp` raising confusing error message when year, month or day is missing (:issue:`31200`) - Bug in :class:`DatetimeIndex` constructor incorrectly accepting ``bool``-dtyped inputs (:issue:`32668`) - Bug in :meth:`DatetimeIndex.searchsorted` not accepting a ``list`` or :class:`Series` as its argument (:issue:`32762`) +- Bug where :meth:`PeriodIndex` raised when passed a :class:`Series` of strings (:issue:`26109`) Timedelta ^^^^^^^^^ diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 39a3b553b3cf4..c2df37f2339e9 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -27,6 +27,7 @@ ensure_object, is_datetime64_dtype, is_float_dtype, + is_list_like, is_period_dtype, pandas_dtype, ) @@ -831,11 +832,11 @@ def period_array( """ if is_datetime64_dtype(data): return PeriodArray._from_datetime64(data, freq) - if isinstance(data, (ABCPeriodIndex, ABCSeries, PeriodArray)): + if is_period_dtype(data): return PeriodArray(data, freq) # other iterable of some kind - if not isinstance(data, (np.ndarray, list, tuple)): + if not is_list_like(data): data = list(data) data = np.asarray(data) diff --git a/pandas/tests/arrays/test_datetimelike.py b/pandas/tests/arrays/test_datetimelike.py index 83995ab26cb56..a3026d30bc3c8 100644 --- a/pandas/tests/arrays/test_datetimelike.py +++ b/pandas/tests/arrays/test_datetimelike.py @@ -868,3 +868,10 @@ def test_searchsorted_datetimelike_with_listlike_invalid_dtype(values, arg): msg = "[Unexpected type|Cannot compare]" with pytest.raises(TypeError, match=msg): values.searchsorted(arg) + + +@pytest.mark.parametrize("klass", [list, tuple, np.array, pd.Series]) +def test_index_constructor_from_string(klass): + result = PeriodIndex(klass(["2020Q1", "2020Q2", "2020Q3", "2020Q4"]), freq="Q") + expected = pd.period_range(start="2020", periods=4, freq="Q") + tm.assert_index_equal(result, expected) From a95ec4ec8aa436e9e2470285025548d371d261c7 Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Sun, 5 Apr 2020 14:01:21 -0500 Subject: [PATCH 2/5] Test name --- pandas/tests/arrays/test_datetimelike.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/arrays/test_datetimelike.py b/pandas/tests/arrays/test_datetimelike.py index a3026d30bc3c8..014e94ab10efe 100644 --- a/pandas/tests/arrays/test_datetimelike.py +++ b/pandas/tests/arrays/test_datetimelike.py @@ -871,7 +871,7 @@ def test_searchsorted_datetimelike_with_listlike_invalid_dtype(values, arg): @pytest.mark.parametrize("klass", [list, tuple, np.array, pd.Series]) -def test_index_constructor_from_string(klass): +def test_period_index_construction_from_strings(klass): result = PeriodIndex(klass(["2020Q1", "2020Q2", "2020Q3", "2020Q4"]), freq="Q") expected = pd.period_range(start="2020", periods=4, freq="Q") tm.assert_index_equal(result, expected) From a4b1bb44139c50d8c23a1e47f8953776956714d0 Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Mon, 6 Apr 2020 07:50:14 -0500 Subject: [PATCH 3/5] Update --- pandas/tests/arrays/test_datetimelike.py | 9 ++++++--- pandas/tests/arrays/test_period.py | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pandas/tests/arrays/test_datetimelike.py b/pandas/tests/arrays/test_datetimelike.py index 014e94ab10efe..56ee25e2236f7 100644 --- a/pandas/tests/arrays/test_datetimelike.py +++ b/pandas/tests/arrays/test_datetimelike.py @@ -10,7 +10,7 @@ import pandas._testing as tm from pandas.core.arrays import DatetimeArray, PeriodArray, TimedeltaArray from pandas.core.indexes.datetimes import DatetimeIndex -from pandas.core.indexes.period import PeriodIndex +from pandas.core.indexes.period import Period, PeriodIndex from pandas.core.indexes.timedeltas import TimedeltaIndex @@ -872,6 +872,9 @@ def test_searchsorted_datetimelike_with_listlike_invalid_dtype(values, arg): @pytest.mark.parametrize("klass", [list, tuple, np.array, pd.Series]) def test_period_index_construction_from_strings(klass): - result = PeriodIndex(klass(["2020Q1", "2020Q2", "2020Q3", "2020Q4"]), freq="Q") - expected = pd.period_range(start="2020", periods=4, freq="Q") + # https://github.com/pandas-dev/pandas/issues/26109 + strings = ["2020Q1", "2020Q2"] * 2 + data = klass(strings) + result = PeriodIndex(data, freq="Q") + expected = PeriodIndex([Period(s) for s in strings]) tm.assert_index_equal(result, expected) diff --git a/pandas/tests/arrays/test_period.py b/pandas/tests/arrays/test_period.py index 0b95d3aa19366..d3ced2f1b1f07 100644 --- a/pandas/tests/arrays/test_period.py +++ b/pandas/tests/arrays/test_period.py @@ -37,6 +37,7 @@ def test_registered(): ([pd.Period("2017", "D"), None], None, [17167, iNaT]), (pd.Series(pd.date_range("2017", periods=3)), None, [17167, 17168, 17169]), (pd.date_range("2017", periods=3), None, [17167, 17168, 17169]), + (pd.period_range("2017", periods=4, freq="Q"), None, [188, 189, 190, 191]), ], ) def test_period_array_ok(data, freq, expected): From 5c0095ac722cdb9500d1d06bdbe3cc0dcbda307e Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Fri, 10 Apr 2020 08:18:53 -0500 Subject: [PATCH 4/5] Fix check --- pandas/core/arrays/period.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index c2df37f2339e9..0b03a665f216d 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -836,7 +836,7 @@ def period_array( return PeriodArray(data, freq) # other iterable of some kind - if not is_list_like(data): + if not isinstance(data, (np.ndarray, list, tuple, ABCSeries)): data = list(data) data = np.asarray(data) From 483c975f15961e47bbff478a4a33c2332f85b90c Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Fri, 10 Apr 2020 08:48:34 -0500 Subject: [PATCH 5/5] Lint --- pandas/core/arrays/period.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 0b03a665f216d..99d9d69d66ec2 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -27,7 +27,6 @@ ensure_object, is_datetime64_dtype, is_float_dtype, - is_list_like, is_period_dtype, pandas_dtype, )