pyrregular 0.2.1__tar.gz → 0.2.2__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.
- {pyrregular-0.2.1 → pyrregular-0.2.2}/.github/workflows/build.yml +10 -5
- {pyrregular-0.2.1 → pyrregular-0.2.2}/.github/workflows/python-publish.yml +11 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/.github/workflows/sphinx.yml +2 -3
- {pyrregular-0.2.1 → pyrregular-0.2.2}/PKG-INFO +2 -1
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyproject.toml +1 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/_version.py +3 -3
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/accessor.py +2 -2
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/conversion_utils.py +7 -1
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/io_utils.py +46 -2
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/models/ncde.py +1 -29
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/repository.py +5 -2
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular.egg-info/PKG-INFO +2 -1
- pyrregular-0.2.2/pyrregular.egg-info/scm_version.json +8 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/setup.cfg +1 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/tests/test_dataset_loading.py +2 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/tests/test_offline.py +52 -0
- pyrregular-0.2.1/pyrregular.egg-info/scm_version.json +0 -8
- {pyrregular-0.2.1 → pyrregular-0.2.2}/.gitignore +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/.gitmodules +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/.pre-commit-config.yaml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/README.md +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/images/logo_01.png +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/accuracy_mean.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/accuracy_std.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/balanced_accuracy_mean.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/balanced_accuracy_std.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/f1_mean.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/f1_std.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/fit_time_mean.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/fit_time_std.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/jaccard_mean.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/jaccard_std.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/precision_mean.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/precision_std.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/predict_time_mean.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/predict_time_std.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/recall_mean.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/recall_std.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/roc_auc_mean.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/roc_auc_std.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/total_time_mean.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/assets/results/total_time_std.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/docs/Makefile +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/docs/api/index.rst +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/docs/conf.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/docs/index.rst +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/docs/make.bat +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/docs/notebooks/dataset_conversion.ipynb +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/docs/notebooks/quick_start.ipynb +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/docs/notebooks/your_dataset.h5 +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/docs/notebooks/your_original_dataset.csv +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/docs/requirements.txt +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/Abf.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/Ais.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/AllGestureWiimoteX.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/AllGestureWiimoteY.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/AllGestureWiimoteZ.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/Animals.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/AsphaltObstaclesCoordinates.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/AsphaltPavementTypeCoordinates.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/AsphaltRegularityCoordinates.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/CharacterTrajectories.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/CombinedTrajectories.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/DodgerLoopDay.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/DodgerLoopGame.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/DodgerLoopWeekend.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/Garment.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/Geolife.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/GeolifeSupervised.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/GestureMidAirD1.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/GestureMidAirD2.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/GestureMidAirD3.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/GesturePebbleZ1.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/GesturePebbleZ2.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/InsectWingbeat.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/JapaneseVowels.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/Ldfpa.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/MelbournePedestrian.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/Mimic3.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/PLAID.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/Pamap2.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/Physionet2012.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/Physionet2019.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/PickupGestureWiimoteZ.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/Seabirds.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/ShakeGestureWiimoteZ.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/SpokenArabicDigits.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/TDrive.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/Taxi.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/metadata/Vehicles.yml +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/__init__.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/backend.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/data_utils.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/__init__.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/abf.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/ais.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/animals.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/combined_trajectories.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/garment.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/geolife.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/geolife_supervised.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/ldfpa.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/mimic3.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/pamap2.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/physionet2012.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/physionet2019.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/seabirds.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/t_drive.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/taxi.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/datasets/vehicles.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/describe.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/dev/__init__.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/dev/repository_dev.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/models/__init__.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/models/borf.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/models/brits.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/models/grud.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/models/knn.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/models/lgbm.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/models/nodes.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/models/raindrop.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/models/ridge_cv.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/models/rifc.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/models/rocket.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/models/saits.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/models/svm.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/models/timesnet.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/models/torch_dataloader.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/reader_interface.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/registry.txt +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/uea_ucr_datasets.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/wrappers/__init__.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/wrappers/pypots_wrapper.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular/wrappers/tslearn_wrapper.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular.egg-info/SOURCES.txt +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular.egg-info/dependency_links.txt +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular.egg-info/entry_points.txt +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular.egg-info/requires.txt +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular.egg-info/scm_file_list.json +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/pyrregular.egg-info/top_level.txt +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/setup.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/tests/__init__.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/tests/_deprecated/__init__.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/tests/_deprecated/test_dataset_conversion.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/tests/_deprecated/test_dataset_sanity.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/tests/_deprecated/utils.py +0 -0
- {pyrregular-0.2.1 → pyrregular-0.2.2}/tests/constants.py +0 -0
|
@@ -4,15 +4,15 @@ on:
|
|
|
4
4
|
pull_request:
|
|
5
5
|
branches: [ main ]
|
|
6
6
|
workflow_dispatch:
|
|
7
|
-
|
|
8
|
-
types: [ published ]
|
|
7
|
+
workflow_call:
|
|
9
8
|
|
|
10
9
|
jobs:
|
|
11
10
|
build:
|
|
12
11
|
strategy:
|
|
12
|
+
fail-fast: false
|
|
13
13
|
matrix:
|
|
14
14
|
os: [ubuntu-latest]
|
|
15
|
-
python-version: ["3.11"]
|
|
15
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
16
16
|
runs-on: ${{ matrix.os }}
|
|
17
17
|
|
|
18
18
|
steps:
|
|
@@ -35,6 +35,11 @@ jobs:
|
|
|
35
35
|
run: |
|
|
36
36
|
pip install ".[test]"
|
|
37
37
|
|
|
38
|
-
- name: Test with pytest
|
|
38
|
+
- name: Test with pytest (offline)
|
|
39
39
|
run: |
|
|
40
|
-
pytest
|
|
40
|
+
pytest -m "not network"
|
|
41
|
+
|
|
42
|
+
- name: Test with pytest (dataset downloads)
|
|
43
|
+
if: matrix.python-version == '3.11'
|
|
44
|
+
run: |
|
|
45
|
+
pytest -m network
|
|
@@ -8,7 +8,11 @@ permissions:
|
|
|
8
8
|
contents: read
|
|
9
9
|
|
|
10
10
|
jobs:
|
|
11
|
+
test:
|
|
12
|
+
uses: ./.github/workflows/build.yml
|
|
13
|
+
|
|
11
14
|
deploy:
|
|
15
|
+
needs: test
|
|
12
16
|
runs-on: ubuntu-latest
|
|
13
17
|
steps:
|
|
14
18
|
- uses: actions/checkout@v4
|
|
@@ -33,3 +37,10 @@ jobs:
|
|
|
33
37
|
with:
|
|
34
38
|
user: __token__
|
|
35
39
|
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
40
|
+
|
|
41
|
+
docs:
|
|
42
|
+
needs: test
|
|
43
|
+
uses: ./.github/workflows/sphinx.yml
|
|
44
|
+
permissions:
|
|
45
|
+
contents: write
|
|
46
|
+
pages: write
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
name: "docs"
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
release:
|
|
5
|
-
types: [published]
|
|
6
4
|
workflow_dispatch:
|
|
5
|
+
workflow_call:
|
|
7
6
|
|
|
8
7
|
permissions:
|
|
9
8
|
contents: write
|
|
@@ -39,7 +38,7 @@ jobs:
|
|
|
39
38
|
make clean html SPHINXOPTS='-a'
|
|
40
39
|
|
|
41
40
|
- name: Deploy to GitHub Pages
|
|
42
|
-
if: github.ref == 'refs/heads/main'
|
|
41
|
+
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')
|
|
43
42
|
uses: peaceiris/actions-gh-pages@v3
|
|
44
43
|
with:
|
|
45
44
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyrregular
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Irregular time series made easy
|
|
5
5
|
Author: Francesco Spinnato, Cristiano Landi
|
|
6
6
|
Author-email: francesco.spinnato@unipi.it
|
|
@@ -8,6 +8,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
8
8
|
Classifier: Programming Language :: Python :: 3.10
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.11
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
11
12
|
Requires-Python: >=3.10
|
|
12
13
|
Description-Content-Type: text/markdown
|
|
13
14
|
Requires-Dist: awkward
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.2.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 2,
|
|
21
|
+
__version__ = version = '0.2.2'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 2)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'ga0f3c03bc'
|
|
@@ -2,7 +2,7 @@ import numpy as np
|
|
|
2
2
|
import pandas as pd
|
|
3
3
|
import xarray as xr
|
|
4
4
|
|
|
5
|
-
from pyrregular.conversion_utils import _ak_dropnan,
|
|
5
|
+
from pyrregular.conversion_utils import _ak_dropnan, _reset_time_index
|
|
6
6
|
from pyrregular.io_utils import save_to_file
|
|
7
7
|
|
|
8
8
|
|
|
@@ -212,7 +212,7 @@ class IrregularAccessor:
|
|
|
212
212
|
columns[name] = _repeat(coord.values, idx[coord.dims[0]])
|
|
213
213
|
return pd.DataFrame(columns)
|
|
214
214
|
|
|
215
|
-
def to_hdf5(self, filename, compression="gzip", compression_opts=
|
|
215
|
+
def to_hdf5(self, filename, compression="gzip", compression_opts=1):
|
|
216
216
|
save_to_file(
|
|
217
217
|
data_array=self._da,
|
|
218
218
|
filename=filename,
|
|
@@ -134,7 +134,7 @@ def _to_tslearn(X):
|
|
|
134
134
|
return X.swapaxes(1, 2)
|
|
135
135
|
|
|
136
136
|
|
|
137
|
-
def _fill_time_index(arr):
|
|
137
|
+
def _fill_time_index(arr, nan_delta=1):
|
|
138
138
|
T = deepcopy(arr)
|
|
139
139
|
|
|
140
140
|
# time delta
|
|
@@ -143,6 +143,12 @@ def _fill_time_index(arr):
|
|
|
143
143
|
# mean time delta
|
|
144
144
|
delta_mean = np.nanmean(a_diff, axis=2, keepdims=True)
|
|
145
145
|
|
|
146
|
+
nans = np.isnan(delta_mean)
|
|
147
|
+
if np.any(
|
|
148
|
+
nans
|
|
149
|
+
): # this can happen if there is only 1 valid value in the time series
|
|
150
|
+
delta_mean[nans] = nan_delta
|
|
151
|
+
|
|
146
152
|
# last timestep
|
|
147
153
|
last_valid_t = np.nanmax(T, axis=2, keepdims=True)
|
|
148
154
|
|
|
@@ -159,6 +159,30 @@ def _get_metadata(
|
|
|
159
159
|
return dates, ids, signals, n_records
|
|
160
160
|
|
|
161
161
|
|
|
162
|
+
def _check_static(keys, id_name, static_names, hint):
|
|
163
|
+
"""Raise if an id has more than one value for a static column.
|
|
164
|
+
|
|
165
|
+
read_csv identifies an id by the tuple (id, *static values), so a column that
|
|
166
|
+
is not really static would silently split the id into several ones.
|
|
167
|
+
"""
|
|
168
|
+
first = {}
|
|
169
|
+
for key in keys:
|
|
170
|
+
other = first.setdefault(key[0], key)
|
|
171
|
+
if other != key:
|
|
172
|
+
columns = [
|
|
173
|
+
n
|
|
174
|
+
for n, a, b in zip(static_names, other[1:], key[1:])
|
|
175
|
+
if a is not b and a != b
|
|
176
|
+
]
|
|
177
|
+
names = ", ".join(repr(c) for c in columns)
|
|
178
|
+
verb = "is" if len(columns) == 1 else "are"
|
|
179
|
+
raise ValueError(
|
|
180
|
+
f"{names} {verb} not static for {id_name} {key[0]!r} (values "
|
|
181
|
+
f"{other[1:]} and {key[1:]}). A static column must have one value "
|
|
182
|
+
f"per id. {hint}"
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
|
|
162
186
|
def read_csv(
|
|
163
187
|
filenames: str | list | dict,
|
|
164
188
|
ts_id: str = "ts_id",
|
|
@@ -193,6 +217,27 @@ def read_csv(
|
|
|
193
217
|
**kwargs,
|
|
194
218
|
)
|
|
195
219
|
|
|
220
|
+
# a static column must have one value per id, otherwise the id would be split
|
|
221
|
+
_check_static(
|
|
222
|
+
ids,
|
|
223
|
+
ts_id,
|
|
224
|
+
dims["ts_id"],
|
|
225
|
+
hint='If it changes over time, move it to dims["time_id"] or use it as a '
|
|
226
|
+
"signal; if each value should be its own series, include it in the series id.",
|
|
227
|
+
)
|
|
228
|
+
_check_static(
|
|
229
|
+
signals,
|
|
230
|
+
signal_id,
|
|
231
|
+
dims["signal_id"],
|
|
232
|
+
hint="If it differs between series, move it to dims['ts_id'].",
|
|
233
|
+
)
|
|
234
|
+
_check_static(
|
|
235
|
+
dates,
|
|
236
|
+
time_id,
|
|
237
|
+
dims["time_id"],
|
|
238
|
+
hint="If it differs between series, move it to dims['ts_id'] or use it as a signal.",
|
|
239
|
+
)
|
|
240
|
+
|
|
196
241
|
# date strings are parsed before sorting, so the time axis follows real time
|
|
197
242
|
parsed_dates = None
|
|
198
243
|
if time_index_as_datetime and all(isinstance(d[0], str) for d in dates):
|
|
@@ -289,6 +334,5 @@ def read_csv(
|
|
|
289
334
|
|
|
290
335
|
def get_current_aoe_time():
|
|
291
336
|
aoe_tz = timezone(timedelta(hours=-12))
|
|
292
|
-
|
|
293
|
-
current_time_aoe = current_time_utc.replace(tzinfo=timezone.utc).astimezone(aoe_tz)
|
|
337
|
+
current_time_aoe = datetime.now(timezone.utc).astimezone(aoe_tz)
|
|
294
338
|
return current_time_aoe.isoformat()
|
|
@@ -15,38 +15,10 @@ import optax
|
|
|
15
15
|
from sklearn.base import BaseEstimator, ClassifierMixin
|
|
16
16
|
from sklearn.model_selection import train_test_split
|
|
17
17
|
|
|
18
|
+
from pyrregular.conversion_utils import _fill_time_index
|
|
18
19
|
from pyrregular.models.nodes import _standardize
|
|
19
20
|
|
|
20
21
|
|
|
21
|
-
def _fill_time_index(arr, nan_delta=1):
|
|
22
|
-
T = deepcopy(arr)
|
|
23
|
-
|
|
24
|
-
# time delta
|
|
25
|
-
a_diff = T[:, :, 1:] - T[:, :, :-1]
|
|
26
|
-
|
|
27
|
-
# mean time delta
|
|
28
|
-
delta_mean = np.nanmean(a_diff, axis=2, keepdims=True)
|
|
29
|
-
|
|
30
|
-
nans = np.isnan(delta_mean)
|
|
31
|
-
if np.any(
|
|
32
|
-
nans
|
|
33
|
-
): # this can happen if there is only 1 valid value in the time series
|
|
34
|
-
delta_mean[nans] = nan_delta
|
|
35
|
-
|
|
36
|
-
# last timestep
|
|
37
|
-
last_valid_t = np.nanmax(T, axis=2, keepdims=True)
|
|
38
|
-
|
|
39
|
-
# find where the nans are
|
|
40
|
-
nan_mask = np.isnan(T)
|
|
41
|
-
|
|
42
|
-
# where nans are there is an increasing value from 1 to the last nan
|
|
43
|
-
nan_indices = np.cumsum(nan_mask, axis=2)
|
|
44
|
-
|
|
45
|
-
replacement = (last_valid_t + delta_mean * nan_indices)[nan_mask]
|
|
46
|
-
T[nan_mask] = replacement
|
|
47
|
-
return T
|
|
48
|
-
|
|
49
|
-
|
|
50
22
|
def _fill_all_nans_signals(X):
|
|
51
23
|
X_ = deepcopy(X)
|
|
52
24
|
mask = np.sum(np.isnan(X_), axis=2) >= X_.shape[2] - 2
|
|
@@ -25,7 +25,8 @@ def download_dataset_from_huggingface(
|
|
|
25
25
|
if api_token is None:
|
|
26
26
|
raise ValueError("You need to provide an API token to download the dataset")
|
|
27
27
|
downloader = pooch.HTTPDownloader(
|
|
28
|
-
|
|
28
|
+
progressbar=progressbar,
|
|
29
|
+
headers={"Authorization": f"Bearer {api_token}"},
|
|
29
30
|
)
|
|
30
31
|
else:
|
|
31
32
|
downloader = pooch.HTTPDownloader(progressbar=progressbar)
|
|
@@ -35,7 +36,9 @@ def download_dataset_from_huggingface(
|
|
|
35
36
|
def load_dataset_from_file(name, api_token=None):
|
|
36
37
|
if ".h5" not in name:
|
|
37
38
|
name += ".h5"
|
|
38
|
-
file = download_dataset_from_huggingface(
|
|
39
|
+
file = download_dataset_from_huggingface(
|
|
40
|
+
name, use_api_token=api_token is not None, api_token=api_token
|
|
41
|
+
)
|
|
39
42
|
return file
|
|
40
43
|
|
|
41
44
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyrregular
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Irregular time series made easy
|
|
5
5
|
Author: Francesco Spinnato, Cristiano Landi
|
|
6
6
|
Author-email: francesco.spinnato@unipi.it
|
|
@@ -8,6 +8,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
8
8
|
Classifier: Programming Language :: Python :: 3.10
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.11
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
11
12
|
Requires-Python: >=3.10
|
|
12
13
|
Description-Content-Type: text/markdown
|
|
13
14
|
Requires-Dist: awkward
|
|
@@ -355,3 +355,55 @@ def test_version():
|
|
|
355
355
|
import pyrregular
|
|
356
356
|
|
|
357
357
|
assert isinstance(pyrregular.__version__, str) and pyrregular.__version__
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def test_read_csv_rejects_non_static_columns(tmp_path):
|
|
361
|
+
# label changes inside series a: it is not static, so read_csv must not split a
|
|
362
|
+
rows = [
|
|
363
|
+
("a", "s", 1, 1.0, "x"),
|
|
364
|
+
("a", "s", 2, 2.0, "x"),
|
|
365
|
+
("a", "s", 3, 3.0, "y"),
|
|
366
|
+
("b", "s", 1, 5.0, "z"),
|
|
367
|
+
]
|
|
368
|
+
path = tmp_path / "static.csv"
|
|
369
|
+
pd.DataFrame(
|
|
370
|
+
rows, columns=["ts_id", "signal_id", "time_id", "value_id", "label"]
|
|
371
|
+
).to_csv(path, index=False)
|
|
372
|
+
with pytest.raises(ValueError, match="'label' is not static for ts_id 'a'"):
|
|
373
|
+
read_csv(
|
|
374
|
+
path,
|
|
375
|
+
dims={"ts_id": ["label"], "signal_id": [], "time_id": []},
|
|
376
|
+
time_index_as_datetime=False,
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def test_api_token_is_sent(monkeypatch):
|
|
381
|
+
# capture the downloader instead of downloading
|
|
382
|
+
from pyrregular import repository
|
|
383
|
+
|
|
384
|
+
seen = {}
|
|
385
|
+
|
|
386
|
+
def fake_fetch(name, downloader):
|
|
387
|
+
seen["name"], seen["downloader"] = name, downloader
|
|
388
|
+
return "fake/path.h5"
|
|
389
|
+
|
|
390
|
+
monkeypatch.delenv("HF_TOKEN", raising=False)
|
|
391
|
+
monkeypatch.setattr(repository.REPOSITORY, "fetch", fake_fetch)
|
|
392
|
+
assert (
|
|
393
|
+
repository.load_dataset_from_file("Garment", api_token="hf_x") == "fake/path.h5"
|
|
394
|
+
)
|
|
395
|
+
assert seen["name"] == "Garment.h5"
|
|
396
|
+
assert seen["downloader"].kwargs["headers"] == {"Authorization": "Bearer hf_x"}
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
def test_fill_time_index():
|
|
400
|
+
from pyrregular.conversion_utils import _fill_time_index
|
|
401
|
+
|
|
402
|
+
T = np.array(
|
|
403
|
+
[
|
|
404
|
+
[[0.0, 1.0, 3.0, nan, nan]], # mean step 1.5
|
|
405
|
+
[[5.0, nan, nan, nan, nan]], # one timestamp: no step, use nan_delta
|
|
406
|
+
]
|
|
407
|
+
)
|
|
408
|
+
assert_equal_nan(_fill_time_index(T)[:, 0, :], [[0, 1, 3, 4.5, 6], [5, 6, 7, 8, 9]])
|
|
409
|
+
assert_equal_nan(_fill_time_index(T, nan_delta=2)[1, 0], [5, 7, 9, 11, 13])
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|