toolbox-utils 5.2.3__tar.gz → 5.2.4__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 (71) hide show
  1. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/.github/workflows/pypi-package.yml +1 -1
  2. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/CHANGELOG.md +7 -0
  3. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/PKG-INFO +1 -1
  4. toolbox_utils-5.2.4/VERSION +1 -0
  5. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/pyproject.toml +1 -1
  6. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/src/toolbox_utils/tsutils.py +35 -33
  7. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/src/toolbox_utils.egg-info/PKG-INFO +1 -1
  8. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/test_asbestfreq.py +5 -3
  9. toolbox_utils-5.2.3/VERSION +0 -1
  10. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/.deepsource.toml +0 -0
  11. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/.github/dependabot.yml +0 -0
  12. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/.github/workflows/clean-workflow-runs.yml +0 -0
  13. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/.github/workflows/tests.yml +0 -0
  14. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/.gitignore +0 -0
  15. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/.pre-commit-config.yaml +0 -0
  16. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/.sourcery.yaml +0 -0
  17. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/AUTHORS.rst +0 -0
  18. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/BADGES.rst +0 -0
  19. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/CONTRIBUTING.rst +0 -0
  20. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/LICENSE.txt +0 -0
  21. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/README.rst +0 -0
  22. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/docs/Makefile +0 -0
  23. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/docs/authors.rst +0 -0
  24. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/docs/conf.py +0 -0
  25. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/docs/contributing.rst +0 -0
  26. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/docs/index.rst +0 -0
  27. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/docs/license.rst +0 -0
  28. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/docs/make.bat +0 -0
  29. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/docs/readme.rst +0 -0
  30. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/setup.cfg +0 -0
  31. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/src/toolbox_utils/__init__.py +0 -0
  32. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/src/toolbox_utils/readers/__init__.py +0 -0
  33. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/src/toolbox_utils/readers/hbn.py +0 -0
  34. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/src/toolbox_utils/readers/plotgen.py +0 -0
  35. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/src/toolbox_utils/readers/wdm.py +0 -0
  36. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/src/toolbox_utils/utils.py +0 -0
  37. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/src/toolbox_utils.egg-info/SOURCES.txt +0 -0
  38. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/src/toolbox_utils.egg-info/dependency_links.txt +0 -0
  39. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/src/toolbox_utils.egg-info/requires.txt +0 -0
  40. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/src/toolbox_utils.egg-info/top_level.txt +0 -0
  41. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data.wdm +0 -0
  42. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_bi_daily.csv +0 -0
  43. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_bivl.hbn +0 -0
  44. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_end.bivl.csv +0 -0
  45. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_end.daily.csv +0 -0
  46. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_end.monthly.csv +0 -0
  47. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_end.yearly.csv +0 -0
  48. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_flow_stage.xlsx +0 -0
  49. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_period.bivl.csv +0 -0
  50. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_period.daily.csv +0 -0
  51. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_period.monthly.csv +0 -0
  52. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_period.yearly.csv +0 -0
  53. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_plotgen.plt +0 -0
  54. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_simple.csv +0 -0
  55. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_start.bivl.csv +0 -0
  56. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_start.daily.csv +0 -0
  57. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_start.monthly.csv +0 -0
  58. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_start.yearly.csv +0 -0
  59. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_wdm_1.csv +0 -0
  60. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_wdm_2.csv +0 -0
  61. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/data_yearly.hbn +0 -0
  62. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/test_date_slice.py +0 -0
  63. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/test_dateparse.py +0 -0
  64. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/test_extract.py +0 -0
  65. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/test_hbn.py +0 -0
  66. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/test_make_list.py +0 -0
  67. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/test_period_timestamp.py +0 -0
  68. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/test_plotgen.py +0 -0
  69. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/test_range_to_numlist.py +0 -0
  70. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/test_read.py +0 -0
  71. {toolbox_utils-5.2.3 → toolbox_utils-5.2.4}/tests/test_wdm.py +0 -0
@@ -38,7 +38,7 @@ jobs:
38
38
  python -m build
39
39
 
40
40
  - name: Download artifact
41
- uses: actions/download-artifact@v7
41
+ uses: actions/download-artifact@v8
42
42
  with:
43
43
  path: dist
44
44
  merge-multiple: true
@@ -1,3 +1,10 @@
1
+ ## v5.2.4 (2026-03-27)
2
+
3
+ ### Fix
4
+
5
+ - reordered calculation of best frequency in asbestfreq
6
+ - fix column suffixes to join
7
+
1
8
  ## v5.2.3 (2026-03-06)
2
9
 
3
10
  ### Fix
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: toolbox_utils
3
- Version: 5.2.3
3
+ Version: 5.2.4
4
4
  Summary: Python toolbox for common utilities
5
5
  Author-email: Tim Cera <tim@cerazone.net>
6
6
  License: BSD-3-Clause
@@ -0,0 +1 @@
1
+ 5.2.4
@@ -61,7 +61,7 @@ github = "https://github.com/timcera/toolbox_utils"
61
61
  name = "cz_conventional_commits"
62
62
  tag_format = "v$version"
63
63
  update_changelog_on_bump = true
64
- version = "5.2.3"
64
+ version = "5.2.4"
65
65
  version_files = ["VERSION"]
66
66
 
67
67
  [tool.isort]
@@ -1027,7 +1027,6 @@ def make_list(
1027
1027
  )
1028
1028
 
1029
1029
  # At this point 'strorlist' variable should be a list or tuple.
1030
-
1031
1030
  if n is None:
1032
1031
  n = len(strorlist)
1033
1032
 
@@ -1696,9 +1695,9 @@ def asbestfreq(data: DataFrame, force_freq: Optional[str] = None) -> DataFrame:
1696
1695
  2. If data.index.freq is not None, just return.
1697
1696
  3. If data.index.inferred_freq is set use .asfreq.
1698
1697
  4. Use pd.infer_freq - fails if any missing
1699
- 5. Use .is_* functions to establish YE, YS, Y-*, YS-*, Q, QS, M, MS
1700
- 6. Use minimum interval to establish the fixed time periods up to
1698
+ 5. Use minimum interval to establish the fixed time periods up to
1701
1699
  weekly
1700
+ 6. Use .is_* functions to establish YE, YS, Y-*, YS-*, Q, QS, M, MS
1702
1701
  7. Gives up returning None for PANDAS offset string
1703
1702
 
1704
1703
  Parameters
@@ -1737,32 +1736,6 @@ def asbestfreq(data: DataFrame, force_freq: Optional[str] = None) -> DataFrame:
1737
1736
  if infer_freq:
1738
1737
  return _replace_nan_with_na(data, freq=infer_freq)
1739
1738
 
1740
- # At this point pd.infer_freq failed probably because of missing values.
1741
- # The following algorithm would not capture things like BQ, BQS
1742
- # ...etc.
1743
- if np.all(data.index.is_year_end):
1744
- infer_freq = pandas_offset_by_version("YE")
1745
- elif np.all(data.index.is_year_start):
1746
- infer_freq = pandas_offset_by_version("YS")
1747
- elif np.all(data.index.is_quarter_end):
1748
- infer_freq = pandas_offset_by_version("QE")
1749
- elif np.all(data.index.is_quarter_start):
1750
- infer_freq = pandas_offset_by_version("QS")
1751
- elif np.all(data.index.is_month_end):
1752
- if np.all(data.index.month == data.index[0].month):
1753
- # Actually yearly with different ends
1754
- infer_freq = f"YE-{_ANNUALS[data.index[0].month]}"
1755
- else:
1756
- infer_freq = "ME"
1757
- elif np.all(data.index.is_month_start):
1758
- if np.all(data.index.month == data.index[0].month):
1759
- # Actually yearly with different start
1760
- infer_freq = f"YE-{_ANNUALS[data.index[0].month - 1]}"
1761
- else:
1762
- infer_freq = "MS"
1763
- if infer_freq:
1764
- return _replace_nan_with_na(data, freq=infer_freq)
1765
-
1766
1739
  data.index = data.index.astype("datetime64[ns]")
1767
1740
  ndiff = (
1768
1741
  data.index.astype("int64").values[1:] - data.index.astype("int64").values[:-1]
@@ -1810,8 +1783,33 @@ def asbestfreq(data: DataFrame, force_freq: Optional[str] = None) -> DataFrame:
1810
1783
  infer_freq = f"{infer_freq}-{_WEEKLIES[data.index[0].dayofweek]}"
1811
1784
  else:
1812
1785
  infer_freq = "D"
1786
+ if infer_freq:
1787
+ return _replace_nan_with_na(data, freq=infer_freq)
1788
+
1789
+ # At this point pd.infer_freq failed probably because of missing values.
1790
+ # The following algorithm would not capture things like BQ, BQS
1791
+ # ...etc.
1792
+ if np.all(data.index.is_month_start):
1793
+ if np.all(data.index.month == data.index[0].month):
1794
+ # Actually yearly with different start
1795
+ infer_freq = f"YE-{_ANNUALS[data.index[0].month - 1]}"
1796
+ else:
1797
+ infer_freq = "MS"
1798
+ elif np.all(data.index.is_month_end):
1799
+ if np.all(data.index.month == data.index[0].month):
1800
+ # Actually yearly with different ends
1801
+ infer_freq = f"YE-{_ANNUALS[data.index[0].month]}"
1802
+ else:
1803
+ infer_freq = "ME"
1804
+ elif np.all(data.index.is_quarter_end):
1805
+ infer_freq = pandas_offset_by_version("QE")
1806
+ elif np.all(data.index.is_quarter_start):
1807
+ infer_freq = pandas_offset_by_version("QS")
1808
+ elif np.all(data.index.is_year_end):
1809
+ infer_freq = pandas_offset_by_version("YE")
1810
+ elif np.all(data.index.is_year_start):
1811
+ infer_freq = pandas_offset_by_version("YS")
1813
1812
 
1814
- data.index = data.index.astype("datetime64[ns]")
1815
1813
  return _replace_nan_with_na(data, freq=infer_freq)
1816
1814
 
1817
1815
 
@@ -2559,12 +2557,16 @@ def read_iso_ts(
2559
2557
 
2560
2558
  result = pd.DataFrame()
2561
2559
 
2562
- for lres in lresult_list:
2560
+ for counter, lres in enumerate(lresult_list):
2561
+ if counter < 2:
2562
+ lcounter = "_r"
2563
+ else:
2564
+ lcounter = f"_r{counter}"
2563
2565
  if len(offset_set) < 2:
2564
- result = result.join(lres, how="outer", rsuffix="_r")
2566
+ result = result.join(lres, how="outer", rsuffix=f"{lcounter}")
2565
2567
  else:
2566
2568
  result = result.join(
2567
- lres.asfreq(moffset - epoch), how="outer", rsuffix="_r"
2569
+ lres.asfreq(moffset - epoch), how="outer", rsuffix=f"{lcounter}"
2568
2570
  )
2569
2571
  else:
2570
2572
  result = lresult_list[0]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: toolbox_utils
3
- Version: 5.2.3
3
+ Version: 5.2.4
4
4
  Summary: Python toolbox for common utilities
5
5
  Author-email: Tim Cera <tim@cerazone.net>
6
6
  License: BSD-3-Clause
@@ -34,7 +34,11 @@ def create_test_data(start, periods, freq, columns=["value"]):
34
34
  @pytest.mark.parametrize(
35
35
  "test_input, expected",
36
36
  [
37
- # Happy path tests
37
+ pytest.param(
38
+ create_test_data("2010-01-01", 16, pandas_offset_by_version("h")),
39
+ "(H|h)",
40
+ id="hourly_freq_on_jan_01",
41
+ ),
38
42
  pytest.param(create_test_data("2021-01-01", 10, "D"), "D", id="daily_freq"),
39
43
  pytest.param(
40
44
  create_test_data("2021-01-01", 10, pandas_offset_by_version("ME")),
@@ -46,7 +50,6 @@ def create_test_data(start, periods, freq, columns=["value"]):
46
50
  "(YE-DEC|A-DEC)",
47
51
  id="annual_freq",
48
52
  ),
49
- # Edge cases
50
53
  pytest.param(
51
54
  create_test_data("2021-01-01", 10, f"5{pandas_offset_by_version('h')}"),
52
55
  "(5h|5H)",
@@ -57,7 +60,6 @@ def create_test_data(start, periods, freq, columns=["value"]):
57
60
  "(15min|15T)",
58
61
  id="15_minute_freq",
59
62
  ),
60
- # Error cases
61
63
  pytest.param(
62
64
  create_test_data("2021-01-01", 10, "D").iloc[::2], "2D", id="2_day"
63
65
  ),
@@ -1 +0,0 @@
1
- 5.2.3
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes