From 0761f7c921538128aedd21b4425553348f6ef17d Mon Sep 17 00:00:00 2001 From: Tony Bagnall Date: Thu, 6 Jun 2024 20:20:46 +0100 Subject: [PATCH 1/3] deprecate Split mixin --- aeon/transformations/_split.py | 9 +++++++ aeon/transformations/collection/hog1d.py | 6 ++--- aeon/transformations/collection/slope.py | 7 ++--- aeon/utils/__init__.py | 2 ++ aeon/utils/_split.py | 27 +++++++++++++++++++ .../tests/test_split.py | 8 +++--- 6 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 aeon/utils/_split.py rename aeon/{transformations => utils}/tests/test_split.py (71%) diff --git a/aeon/transformations/_split.py b/aeon/transformations/_split.py index bf82d1a20b..a3691281aa 100644 --- a/aeon/transformations/_split.py +++ b/aeon/transformations/_split.py @@ -1,6 +1,15 @@ """SplitsTimeSeries mixin.""" +from deprecated.sphinx import deprecated + +# TODO: remove in v0.11.0 +@deprecated( + version="0.10.0", + reason="SplitsTimeSeries class will be removed in 0.11.0. Use the function " + "split_series in utils instead.", + category=FutureWarning, +) class SplitsTimeSeries: """Split time series mixin.""" diff --git a/aeon/transformations/collection/hog1d.py b/aeon/transformations/collection/hog1d.py index ae6b45a124..1dcc84c62a 100644 --- a/aeon/transformations/collection/hog1d.py +++ b/aeon/transformations/collection/hog1d.py @@ -5,11 +5,11 @@ import numpy as np -from aeon.transformations._split import SplitsTimeSeries from aeon.transformations.collection import BaseCollectionTransformer +from aeon.utils import split_series -class HOG1DTransformer(BaseCollectionTransformer, SplitsTimeSeries): +class HOG1DTransformer(BaseCollectionTransformer): """HOG1D transform. This transformer calculates the HOG1D transform [1] of a collection of time series. @@ -89,7 +89,7 @@ def _calculate_hog1ds(self, X): """ # Firstly, split the time series into approx equal # length intervals - splitTimeSeries = self._split(X) + splitTimeSeries = split_series(X, self.n_intervals) HOG1Ds = [] for x in range(len(splitTimeSeries)): diff --git a/aeon/transformations/collection/slope.py b/aeon/transformations/collection/slope.py index f025364f9d..390f049a64 100644 --- a/aeon/transformations/collection/slope.py +++ b/aeon/transformations/collection/slope.py @@ -7,11 +7,11 @@ import numpy as np -from aeon.transformations._split import SplitsTimeSeries from aeon.transformations.collection import BaseCollectionTransformer +from aeon.utils import split_series -class SlopeTransformer(BaseCollectionTransformer, SplitsTimeSeries): +class SlopeTransformer(BaseCollectionTransformer): """Piecewise slope transformation. Class to perform a slope transformation on a collection of time series. @@ -67,8 +67,9 @@ def _transform(self, X, y=None): for i in range(n_cases): case_data = [] for j in range(n_channels): + splits = split_series(X[i][j], self.n_intervals) # Calculate gradients - res = [self._get_gradient(x) for x in self._split(X[i][j])] + res = [self._get_gradient(x) for x in splits] case_data.append(res) full_data.append(np.asarray(case_data)) diff --git a/aeon/utils/__init__.py b/aeon/utils/__init__.py index 292eca0efc..209bb9ed36 100644 --- a/aeon/utils/__init__.py +++ b/aeon/utils/__init__.py @@ -4,6 +4,7 @@ "get_cutoff", "update_data", "get_window", + "split_series", "ALL_TIME_SERIES_TYPES", "COLLECTIONS_DATA_TYPES", "SERIES_DATA_TYPES", @@ -16,4 +17,5 @@ HIERARCHICAL_DATA_TYPES, SERIES_DATA_TYPES, ) +from aeon.utils._split import split_series from aeon.utils.index_functions import get_cutoff, get_window, update_data diff --git a/aeon/utils/_split.py b/aeon/utils/_split.py new file mode 100644 index 0000000000..12fad048a4 --- /dev/null +++ b/aeon/utils/_split.py @@ -0,0 +1,27 @@ +"""Split function.""" + + +def split_series(X, n_intervals): + """Split a time series into approximately equal intervals. + + Adopted from = https://stackoverflow.com/questions/2130016/ + splitting-a-list-into-n-parts-of-approximately + -equal-length + + Parameters + ---------- + X : a numpy array of shape = [n_timepoints] + + Returns + ------- + output : a numpy array of shape = [self.n_intervals,interval_size] + """ + avg = len(X) / float(n_intervals) + output = [] + beginning = 0.0 + + while beginning < len(X): + output.append(X[int(beginning) : int(beginning + avg)]) + beginning += avg + + return output diff --git a/aeon/transformations/tests/test_split.py b/aeon/utils/tests/test_split.py similarity index 71% rename from aeon/transformations/tests/test_split.py rename to aeon/utils/tests/test_split.py index 881122dd54..3c4f8df751 100644 --- a/aeon/transformations/tests/test_split.py +++ b/aeon/utils/tests/test_split.py @@ -3,7 +3,7 @@ import numpy as np import pytest -from aeon.transformations._split import SplitsTimeSeries +from aeon.utils import split_series X = np.arange(10) testdata = [ @@ -13,11 +13,9 @@ @pytest.mark.parametrize("X,n_intervals,expected", testdata) -def test_split_(X, n_intervals, expected): +def test_split_series(X, n_intervals, expected): """Test the splitting of a time series into multiple intervals.""" - splitter = SplitsTimeSeries() - splitter.n_intervals = n_intervals - res = splitter._split(X) + res = split_series(X, n_intervals) assert len(res) == n_intervals for x, y in zip(res, expected): From 014b94f88eea8aa36bc8625bf2f6de27b639afc2 Mon Sep 17 00:00:00 2001 From: Tony Bagnall Date: Sat, 13 Jul 2024 14:16:29 +0100 Subject: [PATCH 2/3] remove legacy --- aeon/transformations/_split.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/aeon/transformations/_split.py b/aeon/transformations/_split.py index a3691281aa..b4831af399 100644 --- a/aeon/transformations/_split.py +++ b/aeon/transformations/_split.py @@ -3,11 +3,11 @@ from deprecated.sphinx import deprecated -# TODO: remove in v0.11.0 +# TODO: remove in v0.12.0 @deprecated( - version="0.10.0", - reason="SplitsTimeSeries class will be removed in 0.11.0. Use the function " - "split_series in utils instead.", + version="0.11.0", + reason="SplitsTimeSeries class will be removed in 0.12.0 or 1.0.0. Use the " + "function split_series in utils instead.", category=FutureWarning, ) class SplitsTimeSeries: From e07a890097868a07f36ccea0a653e274506f5de5 Mon Sep 17 00:00:00 2001 From: Tony Bagnall Date: Sat, 13 Jul 2024 14:17:34 +0100 Subject: [PATCH 3/3] remove legacy --- aeon/transformations/_split.py | 39 ---------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 aeon/transformations/_split.py diff --git a/aeon/transformations/_split.py b/aeon/transformations/_split.py deleted file mode 100644 index b4831af399..0000000000 --- a/aeon/transformations/_split.py +++ /dev/null @@ -1,39 +0,0 @@ -"""SplitsTimeSeries mixin.""" - -from deprecated.sphinx import deprecated - - -# TODO: remove in v0.12.0 -@deprecated( - version="0.11.0", - reason="SplitsTimeSeries class will be removed in 0.12.0 or 1.0.0. Use the " - "function split_series in utils instead.", - category=FutureWarning, -) -class SplitsTimeSeries: - """Split time series mixin.""" - - def _split(self, X): - """Split a time series into approximately equal intervals. - - Adopted from = https://stackoverflow.com/questions/2130016/ - splitting-a-list-into-n-parts-of-approximately - -equal-length - - Parameters - ---------- - X : a numpy array of shape = [time_n_timepoints] - - Returns - ------- - output : a numpy array of shape = [self.n_intervals,interval_size] - """ - avg = len(X) / float(self.n_intervals) - output = [] - beginning = 0.0 - - while beginning < len(X): - output.append(X[int(beginning) : int(beginning + avg)]) - beginning += avg - - return output