time-split 0.7.1__tar.gz → 1.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {time_split-0.7.1 → time_split-1.0.1}/PKG-INFO +3 -3
- {time_split-0.7.1 → time_split-1.0.1}/pyproject.toml +3 -3
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/__init__.py +1 -1
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/_backend/_splitter.py +9 -3
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/_docstrings.py +2 -1
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/_frontend/_plot.py +4 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/_frontend/_progress.py +33 -14
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/_frontend/_split.py +4 -1
- time_split-1.0.1/src/time_split/app/__init__.py +34 -0
- time_split-1.0.1/src/time_split/app/reexport/__init__.py +41 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/integration/polars/__init__.py +5 -5
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/settings.py +0 -5
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/types.py +23 -5
- time_split-0.7.1/src/time_split/app/__init__.py +0 -11
- time_split-0.7.1/src/time_split/app/reexport/__init__.py +0 -58
- {time_split-0.7.1 → time_split-1.0.1}/LICENSE.md +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/README.md +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/__main__.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/_backend/__init__.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/_backend/_datetime_index_like.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/_backend/_limits.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/_backend/_process_available.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/_backend/_schedule.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/_backend/_span.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/_frontend/__init__.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/_frontend/_to_string.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/_frontend/_weight.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/_support.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/app/_create_explorer_link.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/cli.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/integration/__init__.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/integration/_log_progress.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/integration/base.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/integration/pandas/__init__.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/integration/pandas/_impl.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/integration/polars/_impl.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/integration/sklearn/__init__.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/integration/sklearn/_impl.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/py.typed +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/support/__init__.py +0 -0
- {time_split-0.7.1 → time_split-1.0.1}/src/time_split/support/types.py +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: time-split
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.1
|
|
4
4
|
Summary: Time-based k-fold validation splits for heterogeneous data.
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: hyper,parameter,optimization,cross,validation,time,temporal,heterogenous,data
|
|
7
7
|
Author: Richard Sundqvist
|
|
8
8
|
Author-email: richard.sundqvist@live.se
|
|
9
9
|
Requires-Python: >=3.11
|
|
10
|
-
Classifier: Development Status ::
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
11
|
Classifier: Intended Audience :: Developers
|
|
12
12
|
Classifier: Intended Audience :: Science/Research
|
|
13
13
|
Classifier: Operating System :: POSIX :: Linux
|
|
@@ -28,7 +28,7 @@ Requires-Dist: matplotlib ; extra == "plotting"
|
|
|
28
28
|
Requires-Dist: pandas (>=2.0.3)
|
|
29
29
|
Requires-Dist: rics (>=6.0.1)
|
|
30
30
|
Requires-Dist: seaborn ; extra == "plotting"
|
|
31
|
-
Requires-Dist: time-split-app ; extra == "app"
|
|
31
|
+
Requires-Dist: time-split-app (>=1.1.0) ; extra == "app"
|
|
32
32
|
Project-URL: Bug Tracker, https://github.com/rsundqvist/time-split/issues
|
|
33
33
|
Project-URL: Changelog, https://github.com/rsundqvist/time-split/blob/master/CHANGELOG.md
|
|
34
34
|
Project-URL: Documentation, https://time-split
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "time-split"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "1.0.1"
|
|
4
4
|
description = "Time-based k-fold validation splits for heterogeneous data."
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "Richard Sundqvist", email = "richard.sundqvist@live.se" },
|
|
@@ -9,7 +9,7 @@ license = { text = "MIT" }
|
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
keywords = ["hyper", "parameter", "optimization", "cross", "validation", "time", "temporal", "heterogenous", "data"]
|
|
11
11
|
classifiers = [
|
|
12
|
-
"Development Status ::
|
|
12
|
+
"Development Status :: 5 - Production/Stable",
|
|
13
13
|
"Intended Audience :: Developers",
|
|
14
14
|
"Intended Audience :: Science/Research",
|
|
15
15
|
"Operating System :: POSIX :: Linux",
|
|
@@ -32,7 +32,7 @@ dependencies = [
|
|
|
32
32
|
]
|
|
33
33
|
|
|
34
34
|
[project.optional-dependencies]
|
|
35
|
-
app = ["click", "time-split-app
|
|
35
|
+
app = ["click", "time-split-app >= 1.1.0"]
|
|
36
36
|
plotting = ["matplotlib", "seaborn"]
|
|
37
37
|
|
|
38
38
|
[project.urls]
|
|
@@ -2,7 +2,7 @@ from dataclasses import asdict, dataclass
|
|
|
2
2
|
from typing import cast, get_args
|
|
3
3
|
|
|
4
4
|
from pandas import Timedelta
|
|
5
|
-
from rics.misc import format_kwargs
|
|
5
|
+
from rics.misc import format_kwargs, get_by_full_name
|
|
6
6
|
|
|
7
7
|
from ..settings import misc as settings
|
|
8
8
|
from ..types import (
|
|
@@ -11,6 +11,7 @@ from ..types import (
|
|
|
11
11
|
DatetimeSplitBounds,
|
|
12
12
|
DatetimeSplits,
|
|
13
13
|
ExpandLimits,
|
|
14
|
+
Filter,
|
|
14
15
|
Schedule,
|
|
15
16
|
Span,
|
|
16
17
|
TimedeltaTypes,
|
|
@@ -30,6 +31,7 @@ class DatetimeIndexSplitter:
|
|
|
30
31
|
n_splits: int = 0
|
|
31
32
|
expand_limits: ExpandLimits = "auto"
|
|
32
33
|
ignore_filters: bool = False
|
|
34
|
+
filter: Filter | str | None = None
|
|
33
35
|
|
|
34
36
|
def get_splits(self, available: DatetimeIterable | None = None) -> DatetimeSplits:
|
|
35
37
|
"""Compute a split of given user data."""
|
|
@@ -115,10 +117,14 @@ class DatetimeIndexSplitter:
|
|
|
115
117
|
if self.step < 0: # Poorly documented - might not work as expected?
|
|
116
118
|
splits.reverse()
|
|
117
119
|
|
|
118
|
-
|
|
120
|
+
filter = self.filter
|
|
121
|
+
if filter is None:
|
|
119
122
|
return splits
|
|
120
123
|
|
|
121
|
-
|
|
124
|
+
if isinstance(filter, str):
|
|
125
|
+
filter = cast(Filter, get_by_full_name(filter))
|
|
126
|
+
|
|
127
|
+
return [s for s in splits if filter(*s)]
|
|
122
128
|
|
|
123
129
|
def __post_init__(self) -> None:
|
|
124
130
|
# Verify n_splits
|
|
@@ -30,7 +30,8 @@ _DOCSTRINGS = {
|
|
|
30
30
|
"n_splits": "Maximum number of folds, preferring folds later in the schedule.",
|
|
31
31
|
"available": "Binds `schedule` to a range.",
|
|
32
32
|
"expand_limits": f'A {_OFFSET} used to expand `available` data to its likely `"true"` limits. Pass ``False`` to disable.',
|
|
33
|
-
"
|
|
33
|
+
"filter": "A callable ``(start, mid, end) -> bool`` applied to each fold. Strings are converted using :func:`~rics.misc.get_by_full_name`.",
|
|
34
|
+
"ignore_filters": "Set to ignore filtering parameters (e.g. `step` and `filter`).",
|
|
34
35
|
"USER_GUIDE": (
|
|
35
36
|
"For more information about the `schedule`, `before/after` and `expand_limits`-arguments"
|
|
36
37
|
", see the :ref:`User guide`."
|
|
@@ -18,6 +18,7 @@ from ..types import (
|
|
|
18
18
|
DatetimeSplitBounds,
|
|
19
19
|
DatetimeSplits,
|
|
20
20
|
ExpandLimits,
|
|
21
|
+
Filter,
|
|
21
22
|
Schedule,
|
|
22
23
|
Span,
|
|
23
24
|
)
|
|
@@ -67,6 +68,7 @@ def plot(
|
|
|
67
68
|
n_splits: int = 0,
|
|
68
69
|
available: DatetimeIterable | pd.DataFrame | pd.Series | None = None,
|
|
69
70
|
expand_limits: ExpandLimits = "auto",
|
|
71
|
+
filter: Filter | str | None = None,
|
|
70
72
|
ignore_filters: bool = False,
|
|
71
73
|
# Split plot args
|
|
72
74
|
bar_labels: str | Rows | list[tuple[str, str]] | bool = True,
|
|
@@ -88,6 +90,7 @@ def plot(
|
|
|
88
90
|
available: {available} If `bar_labels` is given but is not a ``list``,
|
|
89
91
|
this data will be used to compute fold sizes.
|
|
90
92
|
expand_limits: {expand_limits}
|
|
93
|
+
filter: {filter}
|
|
91
94
|
ignore_filters: {ignore_filters}
|
|
92
95
|
bar_labels: Labels to draw on the bars. If you pass a string, it will be interpreted as a time unit (see
|
|
93
96
|
:ref:`pandas:timeseries.offset_aliases` for valid frequency strings). Bars will show the number of units
|
|
@@ -128,6 +131,7 @@ def plot(
|
|
|
128
131
|
step=step,
|
|
129
132
|
n_splits=n_splits,
|
|
130
133
|
expand_limits=expand_limits,
|
|
134
|
+
filter=filter,
|
|
131
135
|
ignore_filters=ignore_filters,
|
|
132
136
|
)
|
|
133
137
|
|
|
@@ -1,27 +1,35 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from collections.abc import Callable,
|
|
2
|
+
from collections.abc import Callable, Iterator, MutableMapping, Sequence
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
from time import perf_counter
|
|
5
|
-
from typing import Any, Generic
|
|
5
|
+
from typing import Any, Generic, overload
|
|
6
6
|
|
|
7
7
|
import pandas as pd
|
|
8
8
|
from rics.collections.dicts import flatten_dict
|
|
9
9
|
from rics.strings import format_seconds as fmt_sec
|
|
10
10
|
|
|
11
11
|
from ..settings import log_split_progress as settings
|
|
12
|
-
from ..types import
|
|
12
|
+
from ..types import (
|
|
13
|
+
DatetimeSplitBounds,
|
|
14
|
+
FormatMetrics,
|
|
15
|
+
GetMetrics,
|
|
16
|
+
LogSplitProgress,
|
|
17
|
+
LogSplitProgressLoggerArg,
|
|
18
|
+
MetricsType,
|
|
19
|
+
SplitProgressExtras,
|
|
20
|
+
)
|
|
13
21
|
from ._to_string import _PrettyTimestamp
|
|
14
22
|
|
|
15
23
|
|
|
16
24
|
def log_split_progress(
|
|
17
25
|
splits: Sequence[DatetimeSplitBounds],
|
|
18
26
|
*,
|
|
19
|
-
logger:
|
|
27
|
+
logger: LogSplitProgressLoggerArg = "time_split",
|
|
20
28
|
start_level: int = logging.INFO,
|
|
21
29
|
end_level: int = logging.INFO,
|
|
22
30
|
extra: dict[str, Any] | None = None,
|
|
23
31
|
get_metrics: GetMetrics[MetricsType] | None = None,
|
|
24
|
-
) ->
|
|
32
|
+
) -> LogSplitProgress:
|
|
25
33
|
"""Log iteration progress.
|
|
26
34
|
|
|
27
35
|
Args:
|
|
@@ -40,7 +48,7 @@ def log_split_progress(
|
|
|
40
48
|
:attr:`fold-end message <.settings.log_split_progress.END_MESSAGE>` as-is.
|
|
41
49
|
|
|
42
50
|
Returns:
|
|
43
|
-
|
|
51
|
+
A :class:`.LogSplitProgress` object.
|
|
44
52
|
|
|
45
53
|
Examples:
|
|
46
54
|
Configuring the `logger` name and
|
|
@@ -89,7 +97,8 @@ def log_split_progress(
|
|
|
89
97
|
# Backport of https://github.com/python/cpython/pull/107292
|
|
90
98
|
logger = _MergingLoggerAdapter(logger.logger, logger.extra)
|
|
91
99
|
|
|
92
|
-
|
|
100
|
+
return _ProgressTracker(
|
|
101
|
+
splits,
|
|
93
102
|
logger=logger,
|
|
94
103
|
fold_format=settings.FOLD_FORMAT,
|
|
95
104
|
start_level=start_level,
|
|
@@ -101,11 +110,11 @@ def log_split_progress(
|
|
|
101
110
|
get_metrics=get_metrics,
|
|
102
111
|
format_metrics=settings.FORMAT_METRICS or default_metrics_formatter,
|
|
103
112
|
)
|
|
104
|
-
return track(splits)
|
|
105
113
|
|
|
106
114
|
|
|
107
115
|
@dataclass(frozen=True)
|
|
108
|
-
class _ProgressTracker(Generic[MetricsType]):
|
|
116
|
+
class _ProgressTracker(LogSplitProgress, Generic[MetricsType]):
|
|
117
|
+
splits: Sequence[DatetimeSplitBounds]
|
|
109
118
|
logger: logging.Logger | logging.LoggerAdapter # type: ignore[type-arg]
|
|
110
119
|
fold_format: str
|
|
111
120
|
start_level: int
|
|
@@ -117,13 +126,23 @@ class _ProgressTracker(Generic[MetricsType]):
|
|
|
117
126
|
get_metrics: GetMetrics[MetricsType] | None
|
|
118
127
|
format_metrics: FormatMetrics[MetricsType]
|
|
119
128
|
|
|
120
|
-
|
|
121
|
-
|
|
129
|
+
@overload
|
|
130
|
+
def __getitem__(self, index: int) -> DatetimeSplitBounds: ...
|
|
122
131
|
|
|
123
|
-
|
|
132
|
+
@overload
|
|
133
|
+
def __getitem__(self, index: slice) -> Sequence[DatetimeSplitBounds]: ...
|
|
134
|
+
|
|
135
|
+
def __getitem__(self, index: int | slice) -> DatetimeSplitBounds | Sequence[DatetimeSplitBounds]:
|
|
136
|
+
return self.splits[index]
|
|
137
|
+
|
|
138
|
+
def __len__(self) -> int:
|
|
139
|
+
return len(self.splits)
|
|
140
|
+
|
|
141
|
+
def __iter__(self) -> Iterator[DatetimeSplitBounds]:
|
|
142
|
+
for n, split in enumerate(self.splits, start=1):
|
|
124
143
|
default_extras = SplitProgressExtras[MetricsType](
|
|
125
144
|
n=n,
|
|
126
|
-
n_splits=
|
|
145
|
+
n_splits=len(self.splits),
|
|
127
146
|
start=split.start.isoformat(),
|
|
128
147
|
mid=split.mid.isoformat(),
|
|
129
148
|
end=split.end.isoformat(),
|
|
@@ -131,7 +150,7 @@ class _ProgressTracker(Generic[MetricsType]):
|
|
|
131
150
|
extra = {**self.user_extra, **default_extras}
|
|
132
151
|
kwargs: dict[str, Any] = dict(
|
|
133
152
|
n=n,
|
|
134
|
-
n_splits=
|
|
153
|
+
n_splits=len(self.splits),
|
|
135
154
|
start=_PrettyTimestamp(split.start),
|
|
136
155
|
mid=_PrettyTimestamp(split.mid),
|
|
137
156
|
end=_PrettyTimestamp(split.end),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from .._backend import DatetimeIndexSplitter
|
|
2
2
|
from .._docstrings import docs
|
|
3
|
-
from ..types import DatetimeIterable, DatetimeSplits, ExpandLimits, Schedule, Span
|
|
3
|
+
from ..types import DatetimeIterable, DatetimeSplits, ExpandLimits, Filter, Schedule, Span
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
@docs
|
|
@@ -13,6 +13,7 @@ def split(
|
|
|
13
13
|
n_splits: int = 0,
|
|
14
14
|
available: DatetimeIterable | None = None,
|
|
15
15
|
expand_limits: ExpandLimits = "auto",
|
|
16
|
+
filter: Filter | str | None = None,
|
|
16
17
|
ignore_filters: bool = False,
|
|
17
18
|
) -> DatetimeSplits:
|
|
18
19
|
"""Create time-based cross-validation splits.
|
|
@@ -27,6 +28,7 @@ def split(
|
|
|
27
28
|
n_splits: {n_splits}
|
|
28
29
|
available: {available} Passing a tuple ``(min, max)`` is enough.
|
|
29
30
|
expand_limits: {expand_limits}
|
|
31
|
+
filter: {filter}
|
|
30
32
|
ignore_filters: {ignore_filters}
|
|
31
33
|
|
|
32
34
|
{USER_GUIDE}
|
|
@@ -44,5 +46,6 @@ def split(
|
|
|
44
46
|
step=step,
|
|
45
47
|
n_splits=n_splits,
|
|
46
48
|
expand_limits=expand_limits,
|
|
49
|
+
filter=filter,
|
|
47
50
|
ignore_filters=ignore_filters,
|
|
48
51
|
).get_splits(available)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Supporting functions for the Streamlit companion app.
|
|
2
|
+
|
|
3
|
+
Run ``pip install time-split[app]`` to install the https://github.com/rsundqvist/time-split-app/, or run
|
|
4
|
+
``pip install time-split-app==<version>`` to install the application directly.
|
|
5
|
+
|
|
6
|
+
.. warning::
|
|
7
|
+
|
|
8
|
+
The application API may change without a major version bump.
|
|
9
|
+
|
|
10
|
+
Once installed, the application will be available under the ``time_split_app`` namespace. Key parts of the API of the
|
|
11
|
+
application are documented in the :mod:`.reexport` submodule.
|
|
12
|
+
|
|
13
|
+
Getting started
|
|
14
|
+
---------------
|
|
15
|
+
To start the application directly from the command line, run
|
|
16
|
+
|
|
17
|
+
.. code-block:: bash
|
|
18
|
+
|
|
19
|
+
python -m time_split app start
|
|
20
|
+
|
|
21
|
+
in the terminal. To customize the application, run
|
|
22
|
+
|
|
23
|
+
.. code-block:: bash
|
|
24
|
+
|
|
25
|
+
python -m time_split app new
|
|
26
|
+
|
|
27
|
+
in the terminal, then modify the ``Dockerfile`` and ``my_extensions.py`` files to suit your needs.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
from ._create_explorer_link import create_explorer_link
|
|
31
|
+
|
|
32
|
+
__all__ = [
|
|
33
|
+
"create_explorer_link",
|
|
34
|
+
]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Reexported members of the ``time_split_app`` namespace.
|
|
2
|
+
|
|
3
|
+
.. warning::
|
|
4
|
+
|
|
5
|
+
The application API may change without a major version bump.
|
|
6
|
+
|
|
7
|
+
See :mod:`time_split_app.config` for variable-based configuration options.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from time_split_app.datasets import Dataset, DatasetConfig, DuplicateIndexError, load_dataset, load_dataset_configs
|
|
11
|
+
from time_split_app.widgets import DataLoaderWidget, DurationWidget, select_datetime, select_duration
|
|
12
|
+
from time_split_app.widgets import types as _types
|
|
13
|
+
from time_split_app.widgets.types import QueryParams
|
|
14
|
+
|
|
15
|
+
SelectSplitParams = _types.SelectSplitParams
|
|
16
|
+
"""Type of :attr:`~time_split_app.config.SPLIT_SELECT_FN`.
|
|
17
|
+
|
|
18
|
+
See Also:
|
|
19
|
+
* :func:`time_split.split`
|
|
20
|
+
* :attr:`~time_split.types.DatetimeIndexSplitterKwargs`.
|
|
21
|
+
"""
|
|
22
|
+
PlotFn = _types.PlotFn
|
|
23
|
+
"""Type of :attr:`~time_split_app.config.PLOT_FN`."""
|
|
24
|
+
LinkFn = _types.LinkFn
|
|
25
|
+
"""Type of :attr:`~time_split_app.config.LINK_FN`."""
|
|
26
|
+
|
|
27
|
+
__all__ = [
|
|
28
|
+
"DataLoaderWidget",
|
|
29
|
+
"Dataset",
|
|
30
|
+
"DatasetConfig",
|
|
31
|
+
"DuplicateIndexError",
|
|
32
|
+
"DurationWidget",
|
|
33
|
+
"LinkFn",
|
|
34
|
+
"PlotFn",
|
|
35
|
+
"QueryParams",
|
|
36
|
+
"SelectSplitParams",
|
|
37
|
+
"load_dataset",
|
|
38
|
+
"load_dataset_configs",
|
|
39
|
+
"select_datetime",
|
|
40
|
+
"select_duration",
|
|
41
|
+
]
|
|
@@ -19,11 +19,11 @@ Examples:
|
|
|
19
19
|
│ --- ┆ --- │
|
|
20
20
|
│ datetime[μs] ┆ i64 │
|
|
21
21
|
╞═════════════════════╪══════╡
|
|
22
|
-
│ 2022-01-
|
|
23
|
-
│ 2022-01-
|
|
24
|
-
│ 2022-01-
|
|
25
|
-
│ 2022-01-01
|
|
26
|
-
│ 2022-01-
|
|
22
|
+
│ 2022-01-02 05:00:00 ┆ 29 │
|
|
23
|
+
│ 2022-01-01 20:00:00 ┆ 20 │
|
|
24
|
+
│ 2022-01-07 12:00:00 ┆ 156 │
|
|
25
|
+
│ 2022-01-01 18:00:00 ┆ 18 │
|
|
26
|
+
│ 2022-01-04 10:00:00 ┆ 82 │
|
|
27
27
|
└─────────────────────┴──────┘
|
|
28
28
|
|
|
29
29
|
To split the frame, pass it to ``split_polars`` along with the column to split on. The `schedule` keyword argument
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import typing as _t
|
|
4
4
|
|
|
5
|
-
import pandas as _pd
|
|
6
|
-
|
|
7
5
|
from . import types as _tst
|
|
8
6
|
|
|
9
7
|
|
|
@@ -175,9 +173,6 @@ class misc: # noqa: N801
|
|
|
175
173
|
Otherwise, alignment is determined by :func:`pandas.date_range`.
|
|
176
174
|
"""
|
|
177
175
|
|
|
178
|
-
filter: _t.Callable[[_pd.Timestamp, _pd.Timestamp, _pd.Timestamp], bool] | None = None
|
|
179
|
-
"""A callable ``(start, mid, end) -> bool`` applied to all generated folds."""
|
|
180
|
-
|
|
181
176
|
round_limits: bool = False
|
|
182
177
|
"""If ``True``, use rounding instead of ``floor`` and ``ceil`` for limits expansion.
|
|
183
178
|
|
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
import datetime as _dt
|
|
4
4
|
import logging as _logging
|
|
5
5
|
import typing as _t
|
|
6
|
+
from abc import ABC as _ABC
|
|
7
|
+
from collections import abc as _abc
|
|
6
8
|
|
|
7
9
|
import numpy as _np
|
|
8
10
|
import pandas as _pd
|
|
9
11
|
|
|
10
12
|
DatetimeTypes: _t.TypeAlias = str | _pd.Timestamp | _dt.datetime | _dt.date | _np.datetime64
|
|
11
13
|
"""Types that may be cast to :class:`pandas.Timestamp`."""
|
|
12
|
-
DatetimeIterable =
|
|
14
|
+
DatetimeIterable = _abc.Iterable[DatetimeTypes]
|
|
13
15
|
"""Iterable that may be cast to :class:`pandas.DatetimeIndex`."""
|
|
14
16
|
TimedeltaTypes: _t.TypeAlias = str | _pd.Timedelta | _dt.timedelta | _np.timedelta64
|
|
15
17
|
"""Types that may be cast to :class:`pandas.Timedelta`."""
|
|
@@ -21,6 +23,9 @@ Span = int | _t.Literal["all"] | TimedeltaTypes
|
|
|
21
23
|
ExpandLimits = bool | _t.Literal["auto"] | str
|
|
22
24
|
"""Limits flexibility spec for ``floor/ceil``. Pass ``False`` to disable."""
|
|
23
25
|
|
|
26
|
+
Filter = _t.Callable[[_pd.Timestamp, _pd.Timestamp, _pd.Timestamp], bool]
|
|
27
|
+
"""A callable ``(start, mid, end) -> bool`` used to filter folds."""
|
|
28
|
+
|
|
24
29
|
|
|
25
30
|
class DatetimeSplitBounds(_t.NamedTuple):
|
|
26
31
|
"""A 3-tuple which denotes two adjacent datetime ranges."""
|
|
@@ -63,11 +68,11 @@ class DatetimeIndexSplitterKwargs(_t.TypedDict, total=False):
|
|
|
63
68
|
step: int
|
|
64
69
|
n_splits: int
|
|
65
70
|
expand_limits: ExpandLimits
|
|
71
|
+
filter: Filter | str | None
|
|
66
72
|
|
|
67
73
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
LogSplitProgressLoggerArg = _logging.Logger | _logging.LoggerAdapter[_t.Any] | str
|
|
75
|
+
"""A logger or string."""
|
|
71
76
|
MetricsType = _t.TypeVar("MetricsType")
|
|
72
77
|
"""Metrics argument type."""
|
|
73
78
|
GetMetrics = _t.Callable[[_pd.Timestamp], MetricsType]
|
|
@@ -79,7 +84,7 @@ FormatMetrics = _t.Callable[[str, MetricsType], str]
|
|
|
79
84
|
class LogSplitProgressKwargs(_t.TypedDict, _t.Generic[MetricsType], total=False):
|
|
80
85
|
"""Keyword arguments for by :func:`.log_split_progress`."""
|
|
81
86
|
|
|
82
|
-
logger:
|
|
87
|
+
logger: LogSplitProgressLoggerArg
|
|
83
88
|
start_level: int
|
|
84
89
|
end_level: int
|
|
85
90
|
extra: dict[str, _t.Any] | None
|
|
@@ -103,3 +108,16 @@ class SplitProgressExtras(_t.TypedDict, _t.Generic[MetricsType]):
|
|
|
103
108
|
"""User time for the fold. Available only for the :attr:`fold-end message <.settings.log_split_progress.END_MESSAGE>`."""
|
|
104
109
|
metrics: _t.NotRequired[MetricsType]
|
|
105
110
|
"""Optional fold metrics. Typically appended to the :attr:`fold-end message <.settings.log_split_progress.END_MESSAGE>`."""
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class LogSplitProgress(_ABC, _abc.Sequence[DatetimeSplitBounds]):
|
|
114
|
+
"""The sequence-like return type of :func:`.log_split_progress`.
|
|
115
|
+
|
|
116
|
+
A sequence ``[(start, mid, end), ...]`` which logs progress when iterating.
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
splits: _abc.Sequence[DatetimeSplitBounds]
|
|
120
|
+
"""The underlying splits."""
|
|
121
|
+
|
|
122
|
+
logger: _logging.Logger | _logging.LoggerAdapter # type: ignore[type-arg]
|
|
123
|
+
"""Logger instance that emits messages."""
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"""Supporting functions for the Streamlit companion app.
|
|
2
|
-
|
|
3
|
-
The app may be installed by running ``pip install time-split[app]``. The application API is *not* stable, but will be
|
|
4
|
-
available under the ``time_split_app`` namespace. Repo: https://github.com/rsundqvist/time-split-app/.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from ._create_explorer_link import create_explorer_link
|
|
8
|
-
|
|
9
|
-
__all__ = [
|
|
10
|
-
"create_explorer_link",
|
|
11
|
-
]
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
"""Reexported resources from the ``time_split_app`` namespace.
|
|
2
|
-
|
|
3
|
-
Running ``python -m time_split app new`` will create a ``Dockerfile`` and a simple ``my_extensions.py`` module.
|
|
4
|
-
|
|
5
|
-
Environment variables:
|
|
6
|
-
Subset of variables used to customize Docker-based deployments.
|
|
7
|
-
|
|
8
|
-
.. envvar:: DATASET_LOADER
|
|
9
|
-
|
|
10
|
-
A :class:`DataLoaderWidget` instance or type, e.g. ``my_extensions:MyDatasetLoader``.
|
|
11
|
-
|
|
12
|
-
.. envvar:: SPLIT_SELECT_FN
|
|
13
|
-
|
|
14
|
-
A :attr:`SelectSplitParams`-function, e.g. ``my_extensions:my_select_fn``.
|
|
15
|
-
|
|
16
|
-
.. envvar:: PLOT_FN
|
|
17
|
-
|
|
18
|
-
A :func:`~time_split.plot`-like function, e.g. ``my_extensions:my_plot_fn``.
|
|
19
|
-
|
|
20
|
-
.. envvar:: LINK_FN
|
|
21
|
-
|
|
22
|
-
A :func:`.create_explorer_link`-like function, e.g. ``my_extensions:my_link_fn``.
|
|
23
|
-
|
|
24
|
-
See https://github.com/rsundqvist/time-split-app/blob/master/src/time_split_app/config.py
|
|
25
|
-
for more variable-based configuration options.
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
from time_split_app.datasets import Dataset, DatasetConfig, DuplicateIndexError, load_dataset, load_dataset_configs
|
|
29
|
-
from time_split_app.widgets import DataLoaderWidget, DurationWidget, select_datetime, select_duration
|
|
30
|
-
from time_split_app.widgets import types as _types
|
|
31
|
-
from time_split_app.widgets.types import QueryParams
|
|
32
|
-
|
|
33
|
-
SelectSplitParams = _types.SelectSplitParams
|
|
34
|
-
"""Type of :envvar:`SPLIT_SELECT_FN`.
|
|
35
|
-
|
|
36
|
-
A callable ``() -> split_params``; see :func:`time_split.split`
|
|
37
|
-
and :attr:`~time_split.types.DatetimeIndexSplitterKwargs`.
|
|
38
|
-
"""
|
|
39
|
-
PlotFn = _types.PlotFn
|
|
40
|
-
"""Type of :envvar:`PLOT_FN`."""
|
|
41
|
-
LinkFn = _types.LinkFn
|
|
42
|
-
"""Type of :envvar:`LINK_FN`."""
|
|
43
|
-
|
|
44
|
-
__all__ = [
|
|
45
|
-
"DataLoaderWidget",
|
|
46
|
-
"Dataset",
|
|
47
|
-
"DatasetConfig",
|
|
48
|
-
"DuplicateIndexError",
|
|
49
|
-
"DurationWidget",
|
|
50
|
-
"LinkFn",
|
|
51
|
-
"PlotFn",
|
|
52
|
-
"QueryParams",
|
|
53
|
-
"SelectSplitParams",
|
|
54
|
-
"load_dataset",
|
|
55
|
-
"load_dataset_configs",
|
|
56
|
-
"select_datetime",
|
|
57
|
-
"select_duration",
|
|
58
|
-
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|