From 32486a55119f645ed176c583d760026724fb8783 Mon Sep 17 00:00:00 2001 From: Michael Marino Date: Wed, 13 May 2020 21:30:50 +0200 Subject: [PATCH 1/6] Set index to self if returned type is a frame --- pandas/core/indexes/extension.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pandas/core/indexes/extension.py b/pandas/core/indexes/extension.py index badf6502aa723..c9367b7e2ee1d 100644 --- a/pandas/core/indexes/extension.py +++ b/pandas/core/indexes/extension.py @@ -10,7 +10,7 @@ from pandas.util._decorators import cache_readonly, doc from pandas.core.dtypes.common import is_dtype_equal, is_object_dtype -from pandas.core.dtypes.generic import ABCSeries +from pandas.core.dtypes.generic import ABCDataFrame, ABCSeries from pandas.core.arrays import ExtensionArray from pandas.core.indexers import deprecate_ndim_indexing @@ -55,6 +55,8 @@ def fget(self): if wrap: if isinstance(result, type(self._data)): return type(self)._simple_new(result, name=self.name) + elif isinstance(result, ABCDataFrame): + return result.set_index(self) return Index(result, name=self.name) return result @@ -77,6 +79,8 @@ def method(self, *args, **kwargs): if wrap: if isinstance(result, type(self._data)): return type(self)._simple_new(result, name=self.name) + elif isinstance(result, ABCDataFrame): + return result.set_index(self) return Index(result, name=self.name) return result From fd6bd8663f9f66be4e9cda1450ec9f1dc35e70a7 Mon Sep 17 00:00:00 2001 From: Michael Marino Date: Wed, 13 May 2020 21:31:44 +0200 Subject: [PATCH 2/6] Request wrapping for isocalendar in inherit_names --- pandas/core/indexes/datetimes.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 47c50dd2c7b14..9a1e750c5de93 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -66,7 +66,7 @@ def _new_DatetimeIndex(cls, d): @inherit_names( - ["to_period", "to_perioddelta", "to_julian_date", "strftime"] + ["to_period", "to_perioddelta", "to_julian_date", "strftime", "isocalendar"] + DatetimeArray._field_ops + DatetimeArray._datetimelike_methods, DatetimeArray, @@ -90,7 +90,6 @@ def _new_DatetimeIndex(cls, d): "date", "time", "timetz", - "isocalendar", ] + DatetimeArray._bool_ops, DatetimeArray, From aa39030dc7316fc35a242283ebd15d7cc6edaa6c Mon Sep 17 00:00:00 2001 From: Michael Marino Date: Wed, 13 May 2020 21:35:05 +0200 Subject: [PATCH 3/6] Update documentation --- doc/source/user_guide/timeseries.rst | 1 + pandas/core/arrays/datetimes.py | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/doc/source/user_guide/timeseries.rst b/doc/source/user_guide/timeseries.rst index a4e458032b787..5351c3ee6b624 100644 --- a/doc/source/user_guide/timeseries.rst +++ b/doc/source/user_guide/timeseries.rst @@ -793,6 +793,7 @@ You may obtain the year, week and day components of the ISO year from the ISO 86 .. ipython:: python idx = pd.date_range(start='2019-12-29', freq='D', periods=4) + idx.isocalendar() idx.to_series().dt.isocalendar() .. _timeseries.offsets: diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 50d792aeb12f4..894a519cb693e 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -1272,17 +1272,17 @@ def isocalendar(self): -------- >>> idx = pd.date_range(start='2019-12-29', freq='D', periods=4) >>> idx.isocalendar() - year week day - 0 2019 52 7 - 1 2020 1 1 - 2 2020 1 2 - 3 2020 1 3 + year week day + 2019-12-29 2019 52 7 + 2019-12-30 2020 1 1 + 2019-12-31 2020 1 2 + 2020-01-01 2020 1 3 >>> idx.isocalendar().week - 0 52 - 1 1 - 2 1 - 3 1 - Name: week, dtype: UInt32 + 2019-12-29 52 + 2019-12-30 1 + 2019-12-31 1 + 2020-01-01 1 + Freq: D, Name: week, dtype: UInt32 """ from pandas import DataFrame From dd26b8c94170c62f05b82920fbd56bf3e245800d Mon Sep 17 00:00:00 2001 From: Michael Marino Date: Wed, 13 May 2020 21:35:25 +0200 Subject: [PATCH 4/6] Update test to remove set_index --- pandas/tests/groupby/transform/test_transform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/groupby/transform/test_transform.py b/pandas/tests/groupby/transform/test_transform.py index 7997247ca0307..b3347b3c64e6c 100644 --- a/pandas/tests/groupby/transform/test_transform.py +++ b/pandas/tests/groupby/transform/test_transform.py @@ -1022,7 +1022,7 @@ def test_groupby_transform_with_datetimes(func, values): dates = pd.date_range("1/1/2011", periods=10, freq="D") stocks = pd.DataFrame({"price": np.arange(10.0)}, index=dates) - stocks["week_id"] = dates.isocalendar().set_index(dates).week + stocks["week_id"] = dates.isocalendar().week result = stocks.groupby(stocks["week_id"])["price"].transform(func) From 5436de5b946a8174ca1fb21f56dd9759b179eff8 Mon Sep 17 00:00:00 2001 From: Michael Marino Date: Wed, 13 May 2020 22:30:57 +0200 Subject: [PATCH 5/6] Add dates as index to expected dataframe --- pandas/tests/indexes/datetimes/test_misc.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tests/indexes/datetimes/test_misc.py b/pandas/tests/indexes/datetimes/test_misc.py index b9373328eb87f..51841727d510b 100644 --- a/pandas/tests/indexes/datetimes/test_misc.py +++ b/pandas/tests/indexes/datetimes/test_misc.py @@ -404,6 +404,7 @@ def test_isocalendar_returns_correct_values_close_to_new_year_with_tz(): expected_data_frame = pd.DataFrame( [[2013, 52, 7], [2014, 1, 1], [2014, 1, 2]], columns=["year", "week", "day"], + index=dates, dtype="UInt32", ) tm.assert_frame_equal(result, expected_data_frame) From 8ada77d774111b392459de4358c6235ebd40d4a4 Mon Sep 17 00:00:00 2001 From: Michael Marino Date: Wed, 27 May 2020 06:24:20 +0200 Subject: [PATCH 6/6] Add issue number to what's new entry --- doc/source/whatsnew/v1.1.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index c33cd505d0948..8b141965bbfe1 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -209,7 +209,7 @@ Other enhancements - :class:`Series.str` now has a `fullmatch` method that matches a regular expression against the entire string in each row of the series, similar to `re.fullmatch` (:issue:`32806`). - :meth:`DataFrame.sample` will now also allow array-like and BitGenerator objects to be passed to ``random_state`` as seeds (:issue:`32503`) - :meth:`MultiIndex.union` will now raise `RuntimeWarning` if the object inside are unsortable, pass `sort=False` to suppress this warning (:issue:`33015`) -- :class:`Series.dt` and :class:`DatatimeIndex` now have an `isocalendar` method that returns a :class:`DataFrame` with year, week, and day calculated according to the ISO 8601 calendar (:issue:`33206`). +- :class:`Series.dt` and :class:`DatatimeIndex` now have an `isocalendar` method that returns a :class:`DataFrame` with year, week, and day calculated according to the ISO 8601 calendar (:issue:`33206`, :issue:`34392`). - The :meth:`DataFrame.to_feather` method now supports additional keyword arguments (e.g. to set the compression) that are added in pyarrow 0.17 (:issue:`33422`).