From 7a10fe08627e7ce1ef30b78a3c6d1d6f0088840f Mon Sep 17 00:00:00 2001 From: Pierre Date: Tue, 19 Oct 2021 17:44:31 +0200 Subject: [PATCH 01/10] _season_from_months can now handle np.nan _season_from_months can now handle np.nan and values outside of [1,12] I passed these tests: def test_season(): months = np.array([ 1, 2, 3, 4, 5, np.nan]) assert ( _season_from_months(months) == np.array(['DJF', 'DJF', 'MAM', 'MAM', 'MAM', 'na']) ).all() months = np.array([ 1, 100, 3, 13, 0, -5]) assert ( _season_from_months(months) == np.array(['DJF', 'na', 'MAM', 'na', 'na', 'na']) ).all() months = np.array(range(1, 13)) assert ( _season_from_months(months) == np.array(['DJF', 'DJF', 'MAM', 'MAM', 'MAM', 'JJA', 'JJA', 'JJA', 'SON', 'SON', 'SON', 'DJF']) ).all() test_season() --- xarray/core/accessor_dt.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/xarray/core/accessor_dt.py b/xarray/core/accessor_dt.py index 0965d440fc7..69892304304 100644 --- a/xarray/core/accessor_dt.py +++ b/xarray/core/accessor_dt.py @@ -3,6 +3,7 @@ import numpy as np import pandas as pd +import warnings from .common import ( _contains_datetime_like_objects, @@ -16,9 +17,18 @@ def _season_from_months(months): """Compute season (DJF, MAM, JJA, SON) from month ordinal""" # TODO: Move "season" accessor upstream into pandas - seasons = np.array(["DJF", "MAM", "JJA", "SON"]) + seasons = np.array(["DJF", "MAM", "JJA", "SON", "na"]) months = np.asarray(months) - return seasons[(months // 3) % 4] + + idx = 0 + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', message='invalid value encountered in floor_divide') + warnings.filterwarnings('ignore', message='invalid value encountered in remainder') + idx = (months // 3) % 4 + + idx[ np.isnan(idx) ] = 4 + idx[ (months >= 13) | (months <= 0) ] = 4 + return seasons[ idx.astype(int) ] def _access_through_cftimeindex(values, name): From 38e484ce80f60527f01b31e208a9a328bd8ea198 Mon Sep 17 00:00:00 2001 From: Illviljan <14371165+Illviljan@users.noreply.github.com> Date: Sun, 24 Oct 2021 10:09:19 +0200 Subject: [PATCH 02/10] Run black --- xarray/core/accessor_dt.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/xarray/core/accessor_dt.py b/xarray/core/accessor_dt.py index 69892304304..f1d8e1af150 100644 --- a/xarray/core/accessor_dt.py +++ b/xarray/core/accessor_dt.py @@ -19,16 +19,20 @@ def _season_from_months(months): # TODO: Move "season" accessor upstream into pandas seasons = np.array(["DJF", "MAM", "JJA", "SON", "na"]) months = np.asarray(months) - + idx = 0 with warnings.catch_warnings(): - warnings.filterwarnings('ignore', message='invalid value encountered in floor_divide') - warnings.filterwarnings('ignore', message='invalid value encountered in remainder') + warnings.filterwarnings( + "ignore", message="invalid value encountered in floor_divide" + ) + warnings.filterwarnings( + "ignore", message="invalid value encountered in remainder" + ) idx = (months // 3) % 4 - - idx[ np.isnan(idx) ] = 4 - idx[ (months >= 13) | (months <= 0) ] = 4 - return seasons[ idx.astype(int) ] + + idx[np.isnan(idx)] = 4 + idx[(months >= 13) | (months <= 0)] = 4 + return seasons[idx.astype(int)] def _access_through_cftimeindex(values, name): From f315e7213bccdfb48e0b7bafbff0a179c5ed4ef4 Mon Sep 17 00:00:00 2001 From: Illviljan <14371165+Illviljan@users.noreply.github.com> Date: Sun, 24 Oct 2021 10:11:48 +0200 Subject: [PATCH 03/10] Remove duplicated import --- xarray/core/accessor_dt.py | 1 - 1 file changed, 1 deletion(-) diff --git a/xarray/core/accessor_dt.py b/xarray/core/accessor_dt.py index f1d8e1af150..240ca8a4ec6 100644 --- a/xarray/core/accessor_dt.py +++ b/xarray/core/accessor_dt.py @@ -3,7 +3,6 @@ import numpy as np import pandas as pd -import warnings from .common import ( _contains_datetime_like_objects, From f8e82a93fa9daf2991e64b33b033e3fde048d95a Mon Sep 17 00:00:00 2001 From: Pierre Date: Mon, 25 Oct 2021 15:59:23 +0200 Subject: [PATCH 04/10] returns np.nan and removed the useless attribution returns np.nan and removed the useless attribution when month is not in [1,12] --- xarray/core/accessor_dt.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xarray/core/accessor_dt.py b/xarray/core/accessor_dt.py index 240ca8a4ec6..c3c1a9d68e6 100644 --- a/xarray/core/accessor_dt.py +++ b/xarray/core/accessor_dt.py @@ -16,7 +16,7 @@ def _season_from_months(months): """Compute season (DJF, MAM, JJA, SON) from month ordinal""" # TODO: Move "season" accessor upstream into pandas - seasons = np.array(["DJF", "MAM", "JJA", "SON", "na"]) + seasons = np.array(["DJF", "MAM", "JJA", "SON", np.nan]) months = np.asarray(months) idx = 0 @@ -30,7 +30,6 @@ def _season_from_months(months): idx = (months // 3) % 4 idx[np.isnan(idx)] = 4 - idx[(months >= 13) | (months <= 0)] = 4 return seasons[idx.astype(int)] From 4efe64c618dca1552e18837869b2cb6aa50aa323 Mon Sep 17 00:00:00 2001 From: Pierre Date: Mon, 25 Oct 2021 16:50:41 +0200 Subject: [PATCH 05/10] added test --- xarray/tests/test_accessor_dt.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xarray/tests/test_accessor_dt.py b/xarray/tests/test_accessor_dt.py index 135aa058439..4f88c5b45b5 100644 --- a/xarray/tests/test_accessor_dt.py +++ b/xarray/tests/test_accessor_dt.py @@ -234,6 +234,7 @@ def test_dask_accessor_method(self, method, parameters) -> None: def test_seasons(self) -> None: dates = pd.date_range(start="2000/01/01", freq="M", periods=12) + dates = dates.append(pd.Index([np.nan, np.datetime64('NaT')])) dates = xr.DataArray(dates) seasons = xr.DataArray( [ @@ -249,6 +250,8 @@ def test_seasons(self) -> None: "SON", "SON", "DJF", + np.nan, + np.nan, ] ) From 817b42f3552833a704d7c81faa4357016b9993c3 Mon Sep 17 00:00:00 2001 From: Pierre Date: Tue, 26 Oct 2021 09:47:38 +0200 Subject: [PATCH 06/10] applied black recommendations --- xarray/tests/test_accessor_dt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/tests/test_accessor_dt.py b/xarray/tests/test_accessor_dt.py index 4f88c5b45b5..2d614364bd8 100644 --- a/xarray/tests/test_accessor_dt.py +++ b/xarray/tests/test_accessor_dt.py @@ -234,7 +234,7 @@ def test_dask_accessor_method(self, method, parameters) -> None: def test_seasons(self) -> None: dates = pd.date_range(start="2000/01/01", freq="M", periods=12) - dates = dates.append(pd.Index([np.nan, np.datetime64('NaT')])) + dates = dates.append(pd.Index([np.nan, np.datetime64("NaT")])) dates = xr.DataArray(dates) seasons = xr.DataArray( [ From d12e7c77d65a46914c62fe12e45069e56792f5eb Mon Sep 17 00:00:00 2001 From: Pierre Date: Mon, 10 Jan 2022 16:31:47 +0100 Subject: [PATCH 07/10] Apply suggestions from code review finally, NaT is output as a "nan" string Co-authored-by: Spencer Clark --- xarray/core/accessor_dt.py | 3 +-- xarray/tests/test_accessor_dt.py | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/xarray/core/accessor_dt.py b/xarray/core/accessor_dt.py index c3c1a9d68e6..3d27017c55b 100644 --- a/xarray/core/accessor_dt.py +++ b/xarray/core/accessor_dt.py @@ -16,10 +16,9 @@ def _season_from_months(months): """Compute season (DJF, MAM, JJA, SON) from month ordinal""" # TODO: Move "season" accessor upstream into pandas - seasons = np.array(["DJF", "MAM", "JJA", "SON", np.nan]) + seasons = np.array(["DJF", "MAM", "JJA", "SON", "nan"]) months = np.asarray(months) - idx = 0 with warnings.catch_warnings(): warnings.filterwarnings( "ignore", message="invalid value encountered in floor_divide" diff --git a/xarray/tests/test_accessor_dt.py b/xarray/tests/test_accessor_dt.py index 2d614364bd8..83d702dbb39 100644 --- a/xarray/tests/test_accessor_dt.py +++ b/xarray/tests/test_accessor_dt.py @@ -234,7 +234,7 @@ def test_dask_accessor_method(self, method, parameters) -> None: def test_seasons(self) -> None: dates = pd.date_range(start="2000/01/01", freq="M", periods=12) - dates = dates.append(pd.Index([np.nan, np.datetime64("NaT")])) + dates = dates.append(pd.Index([np.datetime64("NaT")])) dates = xr.DataArray(dates) seasons = xr.DataArray( [ @@ -250,8 +250,7 @@ def test_seasons(self) -> None: "SON", "SON", "DJF", - np.nan, - np.nan, + "nan", ] ) From 8fb78f766fe1b1303fb3bddbc3c16d136c260d25 Mon Sep 17 00:00:00 2001 From: Pierre Date: Mon, 10 Jan 2022 17:26:49 +0100 Subject: [PATCH 08/10] update whatsnew --- doc/whats-new.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index f41e57989be..7621a9945cf 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -52,6 +52,10 @@ Bug fixes - Fix applying function with non-xarray arguments using :py:func:`xr.map_blocks`. By `Cindy Chiao `_. + +- `dt.season `_ can now handle NaN and NaT. (:pull:`5876`). + By `Pierre Loicq `_ and `Spencer Clark `_. + Documentation ~~~~~~~~~~~~~ From 67eedfe7956755326e71659937dbe75d0cad7360 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 10 Jan 2022 16:28:15 +0000 Subject: [PATCH 09/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- doc/whats-new.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 7621a9945cf..6bee0d4d8ae 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -52,10 +52,10 @@ Bug fixes - Fix applying function with non-xarray arguments using :py:func:`xr.map_blocks`. By `Cindy Chiao `_. - + - `dt.season `_ can now handle NaN and NaT. (:pull:`5876`). By `Pierre Loicq `_ and `Spencer Clark `_. - + Documentation ~~~~~~~~~~~~~ From 11d2f131fe2b830ec5d9a9620a6b701724d51c62 Mon Sep 17 00:00:00 2001 From: Pierre Date: Tue, 11 Jan 2022 14:49:17 +0100 Subject: [PATCH 10/10] Correction on the credits Co-authored-by: Spencer Clark --- doc/whats-new.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 6bee0d4d8ae..379c2c9d947 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -54,7 +54,7 @@ Bug fixes By `Cindy Chiao `_. - `dt.season `_ can now handle NaN and NaT. (:pull:`5876`). - By `Pierre Loicq `_ and `Spencer Clark `_. + By `Pierre Loicq `_. Documentation