From 35c249fc3758079205b6baacaf24b89ead8bc702 Mon Sep 17 00:00:00 2001 From: Venaturum Date: Fri, 13 May 2022 10:50:47 +1000 Subject: [PATCH 1/3] bugfix for using :meth:`staircase.Stairs.from_values` with timezone aware DatetimeIndex on `values` argument (#GH145) --- docs/release_notes/changelog.rst | 2 ++ staircase/core/stairs.py | 2 +- tests/test_dates/test_dates_misc.py | 23 +++++++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/docs/release_notes/changelog.rst b/docs/release_notes/changelog.rst index f92a4a5..82097f2 100644 --- a/docs/release_notes/changelog.rst +++ b/docs/release_notes/changelog.rst @@ -7,6 +7,8 @@ Changelog UNRELEASED +- bugfix for using :meth:`staircase.Stairs.from_values` with timezone aware DatetimeIndex on `values` argument (#GH145) + Please list new changes above this comment **v2.4.1 2022-05-09** diff --git a/staircase/core/stairs.py b/staircase/core/stairs.py index 583484b..5b4b3f3 100644 --- a/staircase/core/stairs.py +++ b/staircase/core/stairs.py @@ -115,7 +115,7 @@ def from_values(cls, initial_value, values=None, closed="left"): ): warnings.warn("The index of data is not numeric, or time based") - if np.isinf(values.index).any(): + if is_numeric_dtype(values.index) and np.isinf(values.index).any(): raise ValueError("Invalid value for Series index") if not is_numeric_dtype(values) or not is_number(initial_value): diff --git a/tests/test_dates/test_dates_misc.py b/tests/test_dates/test_dates_misc.py index 8065126..e914c40 100644 --- a/tests/test_dates/test_dates_misc.py +++ b/tests/test_dates/test_dates_misc.py @@ -333,3 +333,26 @@ def test_clip_expected_type(date_func, kwargs): kwargs = {key: timestamp(*val, date_func=date_func) for key, val in kwargs.items()} result = s1(date_func).clip(**kwargs) assert_expected_type(result, date_func) + + +def test_from_values(date_func): + # this corresponds to the step function produced by S1 method + values = pd.Series( + [2, 4.5, 2, -0.5, 0], + index=[ + timestamp(2020, 1, 1, date_func=date_func), + timestamp(2020, 1, 3, date_func=date_func), + timestamp(2020, 1, 5, date_func=date_func), + timestamp(2020, 1, 6, date_func=date_func), + timestamp(2020, 1, 10, date_func=date_func), + ], + ) + + sf = Stairs.from_values( + initial_value=0, + values=values, + ) + + print(sf._data) + print(s1(date_func)._data) + assert sf.identical(s1(date_func)) From 574c8362b137ec6cbdbfc657ec849909e641de0b Mon Sep 17 00:00:00 2001 From: Venaturum Date: Fri, 13 May 2022 11:04:50 +1000 Subject: [PATCH 2/3] refactored dtype checks for from_values --- staircase/core/layering.py | 8 ++++---- staircase/core/stairs.py | 8 ++------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/staircase/core/layering.py b/staircase/core/layering.py index 0873f00..800304d 100644 --- a/staircase/core/layering.py +++ b/staircase/core/layering.py @@ -16,7 +16,7 @@ from staircase.util._decorators import Appender -def _check_args_dtypes(start, end): +def _check_args_dtypes(*vectors): approved_dtypes_checks = [ is_datetime64_any_dtype, is_timedelta64_dtype, @@ -27,11 +27,11 @@ def _check_approved_dtype(vec): approved = any(map(lambda func: func(vec), approved_dtypes_checks)) if not approved: warnings.warn( - f"An argument supplied for 'start' or 'end' has dtype {vec.dtype}. Only numerical, datetime-like, or timedelta dtypes have been tested. Using other dtypes is considered experimental." + f"An argument supplied has dtype {vec.dtype}. Only numerical, datetime-like, or timedelta dtypes have been tested. Using other dtypes is considered experimental." ) - _check_approved_dtype(start) - _check_approved_dtype(end) + for vec in vectors: + _check_approved_dtype(vec) def _check_args_types(start, end): diff --git a/staircase/core/stairs.py b/staircase/core/stairs.py index 5b4b3f3..8e77765 100644 --- a/staircase/core/stairs.py +++ b/staircase/core/stairs.py @@ -22,6 +22,7 @@ from staircase.constants import inf from staircase.core import stats from staircase.core.accessor import CachedAccessor +from staircase.core.layering import _check_args_dtypes from staircase.plotting.accessor import PlotAccessor from staircase.util import _replace_none_with_infs from staircase.util._decorators import Appender @@ -108,12 +109,7 @@ def from_values(cls, initial_value, values=None, closed="left"): if not isinstance(values, pd.Series) or values.empty: raise ValueError("values must be a not empty Series") - if not ( - is_numeric_dtype(values.index) - or is_datetime64_dtype(values.index) - or is_timedelta64_dtype(values.index) - ): - warnings.warn("The index of data is not numeric, or time based") + _check_args_dtypes(values.index) if is_numeric_dtype(values.index) and np.isinf(values.index).any(): raise ValueError("Invalid value for Series index") From 9524ac7a9f542ed75850ec60e9ecd86bfc22ffcf Mon Sep 17 00:00:00 2001 From: venaturum Date: Fri, 13 May 2022 11:19:34 +1000 Subject: [PATCH 3/3] v2.4.2 --- docs/release_notes/changelog.rst | 5 ++++- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/release_notes/changelog.rst b/docs/release_notes/changelog.rst index 82097f2..4529c94 100644 --- a/docs/release_notes/changelog.rst +++ b/docs/release_notes/changelog.rst @@ -7,9 +7,12 @@ Changelog UNRELEASED +Please list new changes above this comment + +**v2.4.2 2022-05-13** + - bugfix for using :meth:`staircase.Stairs.from_values` with timezone aware DatetimeIndex on `values` argument (#GH145) -Please list new changes above this comment **v2.4.1 2022-05-09** diff --git a/pyproject.toml b/pyproject.toml index 155bbb6..14a0f39 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "poetry.masonry.api" [tool.poetry] name = "staircase" -version = "2.4.1" +version = "2.4.2" description = "A data analysis package based on modelling and manipulation of mathematical step functions. Strongly aligned with pandas." readme = "README.md" authors = ["Riley Clement "]