time-split 1.0.4__tar.gz → 1.1.0__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.
Files changed (39) hide show
  1. {time_split-1.0.4 → time_split-1.1.0}/PKG-INFO +1 -1
  2. {time_split-1.0.4 → time_split-1.1.0}/pyproject.toml +9 -9
  3. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/__init__.py +1 -1
  4. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/_backend/_schedule.py +7 -2
  5. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/_backend/_splitter.py +7 -6
  6. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/app/_create_explorer_link.py +2 -2
  7. {time_split-1.0.4 → time_split-1.1.0}/LICENSE.md +0 -0
  8. {time_split-1.0.4 → time_split-1.1.0}/README.md +0 -0
  9. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/__main__.py +0 -0
  10. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/_backend/__init__.py +0 -0
  11. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/_backend/_datetime_index_like.py +0 -0
  12. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/_backend/_limits.py +0 -0
  13. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/_backend/_process_available.py +0 -0
  14. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/_backend/_span.py +0 -0
  15. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/_docstrings.py +0 -0
  16. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/_frontend/__init__.py +0 -0
  17. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/_frontend/_plot.py +0 -0
  18. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/_frontend/_progress.py +0 -0
  19. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/_frontend/_split.py +0 -0
  20. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/_frontend/_to_string.py +0 -0
  21. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/_frontend/_weight.py +0 -0
  22. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/_support.py +0 -0
  23. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/app/__init__.py +0 -0
  24. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/app/reexport/__init__.py +0 -0
  25. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/cli.py +0 -0
  26. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/integration/__init__.py +0 -0
  27. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/integration/_log_progress.py +0 -0
  28. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/integration/base.py +0 -0
  29. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/integration/pandas/__init__.py +0 -0
  30. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/integration/pandas/_impl.py +0 -0
  31. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/integration/polars/__init__.py +0 -0
  32. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/integration/polars/_impl.py +0 -0
  33. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/integration/sklearn/__init__.py +0 -0
  34. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/integration/sklearn/_impl.py +0 -0
  35. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/py.typed +0 -0
  36. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/settings.py +0 -0
  37. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/support/__init__.py +0 -0
  38. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/support/types.py +0 -0
  39. {time_split-1.0.4 → time_split-1.1.0}/src/time_split/types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: time-split
3
- Version: 1.0.4
3
+ Version: 1.1.0
4
4
  Summary: Time-based k-fold validation splits for heterogeneous data.
5
5
  License: MIT
6
6
  License-File: LICENSE.md
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "time-split"
3
- version = "1.0.4"
3
+ version = "1.1.0"
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" },
@@ -53,7 +53,7 @@ poetry-plugin-export = ">=1.8"
53
53
  # Extras that must be available for docs + tests go here. Doc/test-only deps go in their respective groups.
54
54
  croniter = "~6.0.0"
55
55
  pyarrow = "~22.0.0"
56
- polars = { version = "~1.34.0", extras = ["pandas"] }
56
+ polars = { version = "~1.35.2", extras = ["pandas"] }
57
57
 
58
58
  [tool.poetry.group.docs]
59
59
  [tool.poetry.group.docs.dependencies]
@@ -61,10 +61,10 @@ polars = { version = "~1.34.0", extras = ["pandas"] }
61
61
  # description: https://github.com/astropy/astropy/issues/11723
62
62
  # https://github.com/astropy/astropy/pull/12270
63
63
  sphinx = "~8.1.3" # 8.2 breaks xdoc refs in README.md; maybe https://github.com/sphinx-doc/sphinx/issues/13932?
64
- sphinx-gallery = "~0.19.0"
64
+ sphinx-gallery = "~0.20.0"
65
65
  pydata-sphinx-theme = "~0.16.1"
66
66
  myst-parser = "~4.0.1"
67
- ipython = "~9.6.0"
67
+ ipython = "~9.8.0"
68
68
 
69
69
  [tool.poetry.group.notebooks]
70
70
  optional = true
@@ -75,9 +75,9 @@ jupyterlab-execute-time = "*"
75
75
  tqdm = "*"
76
76
 
77
77
  [tool.poetry.group.test.dependencies]
78
- pytest = "~8.4.2"
78
+ pytest = "~9.0.1"
79
79
  xdoctest = "~1.3.0"
80
- coverage = "~7.11.0"
80
+ coverage = "~7.12.0"
81
81
  pytest-cov = "~7.0.0"
82
82
 
83
83
  scikit-learn = "~1.7.2"
@@ -85,10 +85,10 @@ dask = { version = "~2025.10.0", extras = ["dataframe"] }
85
85
 
86
86
  [tool.poetry.group.devops.dependencies]
87
87
  invoke = "~2.2.1"
88
- mypy = "~1.18.2"
89
- ruff = "~0.14.2"
88
+ mypy = "~1.19.0"
89
+ ruff = "~0.14.8"
90
90
 
91
- safety = "~3.6.2"
91
+ safety = "~3.7.0"
92
92
  codespell = "~2.4.1"
93
93
  bump2version = "~1.0.1"
94
94
 
@@ -9,4 +9,4 @@ __all__ = [
9
9
  "split",
10
10
  ]
11
11
 
12
- __version__ = "1.0.4"
12
+ __version__ = "1.1.0"
@@ -2,6 +2,7 @@ from typing import NamedTuple, get_args
2
2
 
3
3
  from pandas import DatetimeIndex, NaT, Timedelta, Timestamp, date_range
4
4
 
5
+ from ..settings import misc as settings
5
6
  from ..types import DatetimeIterable, ExpandLimits, Schedule, TimedeltaTypes
6
7
  from ._limits import LimitsTuple
7
8
  from ._process_available import ProcessAvailableResult, process_available
@@ -46,7 +47,7 @@ def materialize_schedule(
46
47
 
47
48
 
48
49
  def _cron_like(schedule: str) -> bool:
49
- # CroniterBadCronError: Exactly 5 or 6 columns has to be specified for iterator expression.
50
+ # CroniterBadCronError: Exactly 5 or 6 columns have to be specified for iterator expression.
50
51
  return len(schedule.split()) > 4 or schedule[0] == "@" # noqa: PLR2004
51
52
 
52
53
 
@@ -54,7 +55,11 @@ def _from_timedelta(schedule: TimedeltaTypes, limits: LimitsTuple) -> DatetimeIn
54
55
  timedelta = Timedelta(schedule)
55
56
  if timedelta <= Timedelta(0):
56
57
  raise ValueError(f"unbounded {schedule=} must be greater than zero.")
57
- return date_range(*limits, freq=timedelta, inclusive="both")
58
+
59
+ if settings.snap_to_end:
60
+ return date_range(limits[1], limits[0], freq=-timedelta, inclusive="both")[::-1]
61
+ else:
62
+ return date_range(limits[0], limits[1], freq=timedelta, inclusive="both")
58
63
 
59
64
 
60
65
  def _handle_cron(expr: str, min_dt: Timestamp, max_dt: Timestamp) -> DatetimeIndex:
@@ -54,19 +54,20 @@ class DatetimeIndexSplitter:
54
54
  settings.snap_to_end
55
55
  and self.after != "all"
56
56
  and isinstance(self.schedule, types)
57
- and isinstance(self.after, types)
57
+ and isinstance(self.after, (types, int))
58
58
  ):
59
59
  ms = self._snap_to_end(ms)
60
60
 
61
61
  return ms
62
62
 
63
63
  def _snap_to_end(self, ms: MaterializedSchedule) -> MaterializedSchedule:
64
- schedule_frequency = ms.schedule.freq
65
- if schedule_frequency is None:
66
- return ms
64
+ data_end = ms.available_metadata.expanded_limits[1]
65
+ schedule_end = ms.schedule[-1]
67
66
 
68
- from_end = ms.available_metadata.expanded_limits[1] - (ms.schedule[-1] + Timedelta(self.after))
69
- from_end = from_end.floor(schedule_frequency.base) # TODO(settings): should this depend on misc.round_limits?
67
+ from_end = data_end - schedule_end
68
+ if not isinstance(self.after, int):
69
+ after = Timedelta(self.after)
70
+ from_end -= after
70
71
 
71
72
  return ms._replace(schedule=ms.schedule + from_end)
72
73
 
@@ -99,8 +99,8 @@ def _create_query(
99
99
  query = {"data": data, **kwargs}
100
100
  else:
101
101
  splitter = DatetimeIndexSplitter(**kwargs)
102
- _, ms = splitter.get_plot_data(data)
103
- query["data"] = _get_data_param(*ms.available_metadata.limits)
102
+ start, end = splitter._materialize_schedule(data).available_metadata.limits
103
+ query["data"] = _get_data_param(start, end)
104
104
 
105
105
  if skip_default:
106
106
  schedule = kwargs["schedule"]
File without changes
File without changes