pastastore 1.7.1__py3-none-any.whl → 1.8.0__py3-none-any.whl
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.
- docs/conf.py +215 -0
- pastastore/__init__.py +6 -1
- pastastore/base.py +72 -630
- pastastore/connectors.py +876 -18
- pastastore/extensions/hpd.py +220 -37
- pastastore/store.py +238 -110
- pastastore/util.py +1 -1
- pastastore/version.py +1 -1
- {pastastore-1.7.1.dist-info → pastastore-1.8.0.dist-info}/METADATA +40 -39
- pastastore-1.8.0.dist-info/RECORD +28 -0
- {pastastore-1.7.1.dist-info → pastastore-1.8.0.dist-info}/WHEEL +1 -1
- {pastastore-1.7.1.dist-info → pastastore-1.8.0.dist-info}/top_level.txt +2 -0
- tests/conftest.py +169 -0
- tests/test_001_import.py +8 -0
- tests/test_002_connectors.py +277 -0
- tests/test_003_pastastore.py +321 -0
- tests/test_004_yaml.py +135 -0
- tests/test_005_maps_plots.py +81 -0
- tests/test_006_benchmark.py +181 -0
- tests/test_007_hpdextension.py +87 -0
- tests/test_008_stressmodels.py +128 -0
- pastastore-1.7.1.dist-info/RECORD +0 -18
- {pastastore-1.7.1.dist-info → pastastore-1.8.0.dist-info}/LICENSE +0 -0
pastastore/store.py
CHANGED
|
@@ -4,9 +4,8 @@ import json
|
|
|
4
4
|
import logging
|
|
5
5
|
import os
|
|
6
6
|
import warnings
|
|
7
|
-
from concurrent.futures import ProcessPoolExecutor
|
|
8
7
|
from functools import partial
|
|
9
|
-
from typing import Dict, List, Literal, Optional, Tuple, Union
|
|
8
|
+
from typing import Dict, Iterable, List, Literal, Optional, Tuple, Union
|
|
10
9
|
|
|
11
10
|
import numpy as np
|
|
12
11
|
import pandas as pd
|
|
@@ -14,7 +13,6 @@ import pastas as ps
|
|
|
14
13
|
from packaging.version import parse as parse_version
|
|
15
14
|
from pastas.io.pas import pastas_hook
|
|
16
15
|
from tqdm.auto import tqdm
|
|
17
|
-
from tqdm.contrib.concurrent import process_map
|
|
18
16
|
|
|
19
17
|
from pastastore.base import BaseConnector
|
|
20
18
|
from pastastore.connectors import DictConnector
|
|
@@ -624,8 +622,10 @@ class PastaStore:
|
|
|
624
622
|
self,
|
|
625
623
|
statistics: Union[str, List[str]],
|
|
626
624
|
modelnames: Optional[List[str]] = None,
|
|
625
|
+
parallel: bool = False,
|
|
627
626
|
progressbar: Optional[bool] = False,
|
|
628
627
|
ignore_errors: Optional[bool] = False,
|
|
628
|
+
fancy_output: bool = True,
|
|
629
629
|
**kwargs,
|
|
630
630
|
) -> FrameorSeriesUnion:
|
|
631
631
|
"""Get model statistics.
|
|
@@ -643,6 +643,11 @@ class PastaStore:
|
|
|
643
643
|
ignore_errors : bool, optional
|
|
644
644
|
ignore errors when True, i.e. when trying to calculate statistics
|
|
645
645
|
for non-existent model in modelnames, default is False
|
|
646
|
+
parallel : bool, optional
|
|
647
|
+
use parallel processing, by default False
|
|
648
|
+
fancy_output : bool, optional
|
|
649
|
+
only read if parallel=True, if True, return as DataFrame with statistics,
|
|
650
|
+
otherwise return list of results
|
|
646
651
|
**kwargs
|
|
647
652
|
any arguments that can be passed to the methods for calculating
|
|
648
653
|
statistics
|
|
@@ -657,25 +662,39 @@ class PastaStore:
|
|
|
657
662
|
if isinstance(statistics, str):
|
|
658
663
|
statistics = [statistics]
|
|
659
664
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
665
|
+
if parallel:
|
|
666
|
+
kwargs["statistics"] = statistics
|
|
667
|
+
if self.conn.conn_type == "pas":
|
|
668
|
+
kwargs["connector"] = self.conn
|
|
669
|
+
return self.apply(
|
|
670
|
+
"models",
|
|
671
|
+
self.conn._get_statistics,
|
|
672
|
+
modelnames,
|
|
673
|
+
kwargs=kwargs,
|
|
674
|
+
parallel=parallel,
|
|
675
|
+
progressbar=progressbar,
|
|
676
|
+
fancy_output=fancy_output,
|
|
677
|
+
).T # transpose to match serial output
|
|
678
|
+
else:
|
|
679
|
+
# create dataframe for results
|
|
680
|
+
s = pd.DataFrame(index=modelnames, columns=statistics, data=np.nan)
|
|
681
|
+
|
|
682
|
+
# loop through model names
|
|
683
|
+
desc = "Get model statistics"
|
|
684
|
+
for mlname in tqdm(modelnames, desc=desc) if progressbar else modelnames:
|
|
685
|
+
try:
|
|
686
|
+
ml = self.get_models(mlname, progressbar=False)
|
|
687
|
+
except Exception as e:
|
|
688
|
+
if ignore_errors:
|
|
689
|
+
continue
|
|
690
|
+
else:
|
|
691
|
+
raise e
|
|
692
|
+
for stat in statistics:
|
|
693
|
+
value = getattr(ml.stats, stat)(**kwargs)
|
|
694
|
+
s.loc[mlname, stat] = value
|
|
676
695
|
|
|
677
|
-
|
|
678
|
-
|
|
696
|
+
s = s.squeeze()
|
|
697
|
+
return s.astype(float)
|
|
679
698
|
|
|
680
699
|
def create_model(
|
|
681
700
|
self,
|
|
@@ -1235,74 +1254,58 @@ class PastaStore:
|
|
|
1235
1254
|
|
|
1236
1255
|
modelnames = self.conn._parse_names(modelnames, libname="models")
|
|
1237
1256
|
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
report=report,
|
|
1241
|
-
ignore_solve_errors=ignore_solve_errors,
|
|
1242
|
-
**kwargs,
|
|
1243
|
-
)
|
|
1244
|
-
if self.conn.conn_type != "pas":
|
|
1257
|
+
# prepare parallel
|
|
1258
|
+
if parallel and self.conn.conn_type == "dict":
|
|
1245
1259
|
parallel = False
|
|
1246
1260
|
logger.error(
|
|
1247
|
-
"Parallel solving only supported for PasConnector
|
|
1248
|
-
"Setting parallel to `False`"
|
|
1261
|
+
"Parallel solving only supported for PasConnector and "
|
|
1262
|
+
"ArcticDBConnector databases. Setting parallel to `False`"
|
|
1249
1263
|
)
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1264
|
+
if parallel:
|
|
1265
|
+
if self.conn.conn_type == "arcticdb":
|
|
1266
|
+
solve_model = partial(
|
|
1267
|
+
self.conn._solve_model,
|
|
1268
|
+
report=report,
|
|
1269
|
+
ignore_solve_errors=ignore_solve_errors,
|
|
1270
|
+
**kwargs,
|
|
1271
|
+
)
|
|
1272
|
+
self.conn._parallel(
|
|
1273
|
+
solve_model,
|
|
1274
|
+
modelnames,
|
|
1275
|
+
max_workers=max_workers,
|
|
1276
|
+
chunksize=None,
|
|
1277
|
+
progressbar=progressbar,
|
|
1278
|
+
desc="Solving models (parallel)",
|
|
1279
|
+
)
|
|
1280
|
+
elif self.conn.conn_type == "pas":
|
|
1281
|
+
solve_model = partial(
|
|
1282
|
+
self.conn._solve_model,
|
|
1283
|
+
connector=self.conn,
|
|
1284
|
+
report=report,
|
|
1285
|
+
ignore_solve_errors=ignore_solve_errors,
|
|
1286
|
+
**kwargs,
|
|
1287
|
+
)
|
|
1288
|
+
self.conn._parallel(
|
|
1289
|
+
solve_model,
|
|
1290
|
+
modelnames,
|
|
1291
|
+
max_workers=max_workers,
|
|
1292
|
+
chunksize=None,
|
|
1293
|
+
progressbar=progressbar,
|
|
1294
|
+
desc="Solving models (parallel)",
|
|
1295
|
+
)
|
|
1256
1296
|
else:
|
|
1297
|
+
solve_model = partial(
|
|
1298
|
+
self.conn._solve_model,
|
|
1299
|
+
connector=self.conn,
|
|
1300
|
+
report=report,
|
|
1301
|
+
ignore_solve_errors=ignore_solve_errors,
|
|
1302
|
+
**kwargs,
|
|
1303
|
+
)
|
|
1257
1304
|
for ml_name in (
|
|
1258
1305
|
tqdm(modelnames, desc="Solving models") if progressbar else modelnames
|
|
1259
1306
|
):
|
|
1260
1307
|
solve_model(ml_name=ml_name)
|
|
1261
1308
|
|
|
1262
|
-
def _solve_model(
|
|
1263
|
-
self,
|
|
1264
|
-
ml_name: str,
|
|
1265
|
-
report: bool = False,
|
|
1266
|
-
ignore_solve_errors: bool = False,
|
|
1267
|
-
**kwargs,
|
|
1268
|
-
) -> None:
|
|
1269
|
-
"""Solve a model in the store (internal method).
|
|
1270
|
-
|
|
1271
|
-
ml_name : list of str, optional
|
|
1272
|
-
name of a model in the pastastore
|
|
1273
|
-
report : boolean, optional
|
|
1274
|
-
determines if a report is printed when the model is solved,
|
|
1275
|
-
default is False
|
|
1276
|
-
ignore_solve_errors : boolean, optional
|
|
1277
|
-
if True, errors emerging from the solve method are ignored,
|
|
1278
|
-
default is False which will raise an exception when a model
|
|
1279
|
-
cannot be optimized
|
|
1280
|
-
**kwargs : dictionary
|
|
1281
|
-
arguments are passed to the solve method.
|
|
1282
|
-
"""
|
|
1283
|
-
ml = self.conn.get_models(ml_name)
|
|
1284
|
-
m_kwargs = {}
|
|
1285
|
-
for key, value in kwargs.items():
|
|
1286
|
-
if isinstance(value, pd.Series):
|
|
1287
|
-
m_kwargs[key] = value.loc[ml.name]
|
|
1288
|
-
else:
|
|
1289
|
-
m_kwargs[key] = value
|
|
1290
|
-
# Convert timestamps
|
|
1291
|
-
for tstamp in ["tmin", "tmax"]:
|
|
1292
|
-
if tstamp in m_kwargs:
|
|
1293
|
-
m_kwargs[tstamp] = pd.Timestamp(m_kwargs[tstamp])
|
|
1294
|
-
|
|
1295
|
-
try:
|
|
1296
|
-
ml.solve(report=report, **m_kwargs)
|
|
1297
|
-
except Exception as e:
|
|
1298
|
-
if ignore_solve_errors:
|
|
1299
|
-
warning = "Solve error ignored for '%s': %s " % (ml.name, e)
|
|
1300
|
-
logger.warning(warning)
|
|
1301
|
-
else:
|
|
1302
|
-
raise e
|
|
1303
|
-
|
|
1304
|
-
self.conn.add_model(ml, overwrite=True)
|
|
1305
|
-
|
|
1306
1309
|
def model_results(
|
|
1307
1310
|
self,
|
|
1308
1311
|
mls: Optional[Union[ps.Model, list, str]] = None,
|
|
@@ -1443,6 +1446,7 @@ class PastaStore:
|
|
|
1443
1446
|
conn: Optional[BaseConnector] = None,
|
|
1444
1447
|
storename: Optional[str] = None,
|
|
1445
1448
|
progressbar: bool = True,
|
|
1449
|
+
series_ext_json: bool = False,
|
|
1446
1450
|
):
|
|
1447
1451
|
"""Load PastaStore from zipfile.
|
|
1448
1452
|
|
|
@@ -1458,6 +1462,10 @@ class PastaStore:
|
|
|
1458
1462
|
defaults to the name of the Connector.
|
|
1459
1463
|
progressbar : bool, optional
|
|
1460
1464
|
show progressbar, by default True
|
|
1465
|
+
series_ext_json : bool, optional
|
|
1466
|
+
if True, series are expected to have a .json extension, by default False,
|
|
1467
|
+
which assumes a .pas extension. Set this option to true for reading
|
|
1468
|
+
zipfiles created with older versions of pastastore <1.8.0.
|
|
1461
1469
|
|
|
1462
1470
|
Returns
|
|
1463
1471
|
-------
|
|
@@ -1469,9 +1477,22 @@ class PastaStore:
|
|
|
1469
1477
|
if conn is None:
|
|
1470
1478
|
conn = DictConnector("pastas_db")
|
|
1471
1479
|
|
|
1480
|
+
if series_ext_json:
|
|
1481
|
+
ext = "json"
|
|
1482
|
+
else:
|
|
1483
|
+
ext = "pas"
|
|
1484
|
+
|
|
1485
|
+
# short circuit for PasConnector when zipfile was written using pas files
|
|
1486
|
+
if conn.conn_type == "pas" and not series_ext_json:
|
|
1487
|
+
with ZipFile(fname, "r") as archive:
|
|
1488
|
+
archive.extractall(conn.path)
|
|
1489
|
+
if storename is None:
|
|
1490
|
+
storename = conn.name
|
|
1491
|
+
return cls(conn, storename)
|
|
1492
|
+
|
|
1472
1493
|
with ZipFile(fname, "r") as archive:
|
|
1473
1494
|
namelist = [
|
|
1474
|
-
fi for fi in archive.namelist() if not fi.endswith("_meta.
|
|
1495
|
+
fi for fi in archive.namelist() if not fi.endswith(f"_meta.{ext}")
|
|
1475
1496
|
]
|
|
1476
1497
|
for f in tqdm(namelist, desc="Reading zip") if progressbar else namelist:
|
|
1477
1498
|
libname, fjson = os.path.split(f)
|
|
@@ -1480,7 +1501,7 @@ class PastaStore:
|
|
|
1480
1501
|
if not isinstance(s.index, pd.DatetimeIndex):
|
|
1481
1502
|
s.index = pd.to_datetime(s.index, unit="ms")
|
|
1482
1503
|
s = s.sort_index()
|
|
1483
|
-
meta = json.load(archive.open(f.replace(".
|
|
1504
|
+
meta = json.load(archive.open(f.replace(f".{ext}", f"_meta.{ext}")))
|
|
1484
1505
|
conn._add_series(libname, s, fjson.split(".")[0], metadata=meta)
|
|
1485
1506
|
elif libname in ["models"]:
|
|
1486
1507
|
ml = json.load(archive.open(f), object_hook=pastas_hook)
|
|
@@ -1496,7 +1517,7 @@ class PastaStore:
|
|
|
1496
1517
|
case_sensitive: bool = True,
|
|
1497
1518
|
sort=True,
|
|
1498
1519
|
):
|
|
1499
|
-
"""Search for names of time series or models
|
|
1520
|
+
"""Search for names of time series or models containing string `s`.
|
|
1500
1521
|
|
|
1501
1522
|
Parameters
|
|
1502
1523
|
----------
|
|
@@ -1515,30 +1536,45 @@ class PastaStore:
|
|
|
1515
1536
|
list of names that match search result
|
|
1516
1537
|
"""
|
|
1517
1538
|
if libname == "models":
|
|
1518
|
-
lib_names = self.model_names
|
|
1539
|
+
lib_names = {"models": self.model_names}
|
|
1519
1540
|
elif libname == "stresses":
|
|
1520
|
-
lib_names = self.stresses_names
|
|
1541
|
+
lib_names = {"stresses": self.stresses_names}
|
|
1521
1542
|
elif libname == "oseries":
|
|
1522
|
-
lib_names = self.oseries_names
|
|
1543
|
+
lib_names = {"oseries": self.oseries_names}
|
|
1544
|
+
elif libname is None:
|
|
1545
|
+
lib_names = {
|
|
1546
|
+
"oseries": self.oseries_names,
|
|
1547
|
+
"stresses": self.stresses_names,
|
|
1548
|
+
"models": self.model_names,
|
|
1549
|
+
}
|
|
1523
1550
|
else:
|
|
1524
1551
|
raise ValueError("Provide valid libname: 'models', 'stresses' or 'oseries'")
|
|
1525
1552
|
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
else:
|
|
1530
|
-
matches = [n for n in lib_names if s.lower() in n.lower()]
|
|
1531
|
-
if isinstance(s, list):
|
|
1532
|
-
m = np.array([])
|
|
1533
|
-
for sub in s:
|
|
1553
|
+
result = {}
|
|
1554
|
+
for lib, names in lib_names.items():
|
|
1555
|
+
if isinstance(s, str):
|
|
1534
1556
|
if case_sensitive:
|
|
1535
|
-
|
|
1557
|
+
matches = [n for n in names if s in n]
|
|
1536
1558
|
else:
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1559
|
+
matches = [n for n in names if s.lower() in n.lower()]
|
|
1560
|
+
elif isinstance(s, list):
|
|
1561
|
+
m = np.array([])
|
|
1562
|
+
for sub in s:
|
|
1563
|
+
if case_sensitive:
|
|
1564
|
+
m = np.append(m, [n for n in names if sub in n])
|
|
1565
|
+
else:
|
|
1566
|
+
m = np.append(m, [n for n in names if sub.lower() in n.lower()])
|
|
1567
|
+
matches = list(np.unique(m))
|
|
1568
|
+
else:
|
|
1569
|
+
raise TypeError("s must be str or list of str!")
|
|
1570
|
+
if sort:
|
|
1571
|
+
matches.sort()
|
|
1572
|
+
result[lib] = matches
|
|
1573
|
+
|
|
1574
|
+
if len(result) == 1:
|
|
1575
|
+
return result[lib]
|
|
1576
|
+
else:
|
|
1577
|
+
return result
|
|
1542
1578
|
|
|
1543
1579
|
def get_model_timeseries_names(
|
|
1544
1580
|
self,
|
|
@@ -1603,7 +1639,17 @@ class PastaStore:
|
|
|
1603
1639
|
else:
|
|
1604
1640
|
return structure
|
|
1605
1641
|
|
|
1606
|
-
def apply(
|
|
1642
|
+
def apply(
|
|
1643
|
+
self,
|
|
1644
|
+
libname: str,
|
|
1645
|
+
func: callable,
|
|
1646
|
+
names: Optional[Union[str, List[str]]] = None,
|
|
1647
|
+
kwargs: Optional[dict] = None,
|
|
1648
|
+
progressbar: bool = True,
|
|
1649
|
+
parallel: bool = False,
|
|
1650
|
+
max_workers: Optional[int] = None,
|
|
1651
|
+
fancy_output: bool = True,
|
|
1652
|
+
) -> Union[dict, pd.Series, pd.DataFrame]:
|
|
1607
1653
|
"""Apply function to items in library.
|
|
1608
1654
|
|
|
1609
1655
|
Supported libraries are oseries, stresses, and models.
|
|
@@ -1613,32 +1659,114 @@ class PastaStore:
|
|
|
1613
1659
|
libname : str
|
|
1614
1660
|
library name, supports "oseries", "stresses" and "models"
|
|
1615
1661
|
func : callable
|
|
1616
|
-
function that accepts
|
|
1662
|
+
function that accepts a string corresponding to the name of an item in
|
|
1663
|
+
the library as its first argument. Additional keyword arguments can be
|
|
1664
|
+
specified. The function can return any result, or update an item in the
|
|
1665
|
+
database without returning anything.
|
|
1617
1666
|
names : str, list of str, optional
|
|
1618
1667
|
apply function to these names, by default None which loops over all stored
|
|
1619
1668
|
items in library
|
|
1669
|
+
kwargs : dict, optional
|
|
1670
|
+
keyword arguments to pass to func, by default None
|
|
1620
1671
|
progressbar : bool, optional
|
|
1621
1672
|
show progressbar, by default True
|
|
1673
|
+
parallel : bool, optional
|
|
1674
|
+
run apply in parallel, default is False.
|
|
1675
|
+
max_workers : int, optional
|
|
1676
|
+
max no. of workers, only used if parallel is True
|
|
1677
|
+
fancy_output : bool, optional
|
|
1678
|
+
if True, try returning result as pandas Series or DataFrame, by default
|
|
1679
|
+
False
|
|
1622
1680
|
|
|
1623
1681
|
Returns
|
|
1624
1682
|
-------
|
|
1625
1683
|
dict
|
|
1626
1684
|
dict of results of func, with names as keys and results as values
|
|
1685
|
+
|
|
1686
|
+
Notes
|
|
1687
|
+
-----
|
|
1688
|
+
Users should be aware that parallel solving is platform dependent
|
|
1689
|
+
and may not always work. The current implementation works well for Linux users.
|
|
1690
|
+
For Windows users, parallel solving does not work when called directly from
|
|
1691
|
+
Jupyter Notebooks or IPython. To use parallel solving on Windows, the following
|
|
1692
|
+
code should be used in a Python file::
|
|
1693
|
+
|
|
1694
|
+
from multiprocessing import freeze_support
|
|
1695
|
+
|
|
1696
|
+
if __name__ == "__main__":
|
|
1697
|
+
freeze_support()
|
|
1698
|
+
pstore.apply("models", some_func, parallel=True)
|
|
1627
1699
|
"""
|
|
1628
1700
|
names = self.conn._parse_names(names, libname)
|
|
1629
|
-
|
|
1701
|
+
if kwargs is None:
|
|
1702
|
+
kwargs = {}
|
|
1630
1703
|
if libname not in ("oseries", "stresses", "models"):
|
|
1631
1704
|
raise ValueError(
|
|
1632
1705
|
"'libname' must be one of ['oseries', 'stresses', 'models']!"
|
|
1633
1706
|
)
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1707
|
+
if parallel:
|
|
1708
|
+
result = self.conn._parallel(
|
|
1709
|
+
func,
|
|
1710
|
+
kwargs=kwargs,
|
|
1711
|
+
names=names,
|
|
1712
|
+
progressbar=progressbar,
|
|
1713
|
+
max_workers=max_workers,
|
|
1714
|
+
chunksize=None,
|
|
1715
|
+
desc=f"Applying {func.__name__} (parallel)",
|
|
1716
|
+
)
|
|
1717
|
+
else:
|
|
1718
|
+
result = []
|
|
1719
|
+
for n in tqdm(
|
|
1720
|
+
names, desc=f"Applying {func.__name__}", disable=not progressbar
|
|
1721
|
+
):
|
|
1722
|
+
result.append(func(n, **kwargs))
|
|
1723
|
+
if fancy_output:
|
|
1724
|
+
return PastaStore._fancy_output(result, names, func.__name__)
|
|
1725
|
+
else:
|
|
1726
|
+
return result
|
|
1727
|
+
|
|
1728
|
+
@staticmethod
|
|
1729
|
+
def _fancy_output(
|
|
1730
|
+
result: Iterable,
|
|
1731
|
+
names: List[str],
|
|
1732
|
+
label: Optional[str] = None,
|
|
1733
|
+
) -> Union[pd.Series, pd.DataFrame, dict]:
|
|
1734
|
+
"""Convert apply result to pandas Series, DataFrame or dict.
|
|
1640
1735
|
|
|
1641
|
-
|
|
1736
|
+
Parameters
|
|
1737
|
+
----------
|
|
1738
|
+
result : Iterable
|
|
1739
|
+
result of apply function
|
|
1740
|
+
names : list
|
|
1741
|
+
list of names
|
|
1742
|
+
label : str, optional
|
|
1743
|
+
label for columns, by default None
|
|
1744
|
+
|
|
1745
|
+
Returns
|
|
1746
|
+
-------
|
|
1747
|
+
pd.Series, pd.DataFrame, dict
|
|
1748
|
+
Series, DataFrame or dict with results
|
|
1749
|
+
"""
|
|
1750
|
+
if not isinstance(result, list):
|
|
1751
|
+
result = list(result)
|
|
1752
|
+
if isinstance(result[0], (float, int, np.integer)):
|
|
1753
|
+
return pd.Series(result, index=names)
|
|
1754
|
+
elif isinstance(result[0], (pd.Series, pd.DataFrame)):
|
|
1755
|
+
df = pd.concat(dict(zip(names, result, strict=True)), axis=1)
|
|
1756
|
+
if label is not None:
|
|
1757
|
+
df.columns.name = label
|
|
1758
|
+
return df
|
|
1759
|
+
elif result[0] is None:
|
|
1760
|
+
return None # return None if first result is None?
|
|
1761
|
+
else:
|
|
1762
|
+
return dict(zip(names, result, strict=True))
|
|
1763
|
+
|
|
1764
|
+
def within(
|
|
1765
|
+
self,
|
|
1766
|
+
extent: list,
|
|
1767
|
+
names: Optional[list[str]] = None,
|
|
1768
|
+
libname: str = "oseries",
|
|
1769
|
+
):
|
|
1642
1770
|
"""Get names of items within extent.
|
|
1643
1771
|
|
|
1644
1772
|
Parameters
|
pastastore/util.py
CHANGED
pastastore/version.py
CHANGED
|
@@ -9,7 +9,7 @@ PASTAS_VERSION = parse_version(ps.__version__)
|
|
|
9
9
|
PASTAS_LEQ_022 = PASTAS_VERSION <= parse_version("0.22.0")
|
|
10
10
|
PASTAS_GEQ_150 = PASTAS_VERSION >= parse_version("1.5.0")
|
|
11
11
|
|
|
12
|
-
__version__ = "1.
|
|
12
|
+
__version__ = "1.8.0"
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def show_versions(optional=False) -> None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pastastore
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.8.0
|
|
4
4
|
Summary: Tools for managing Pastas time series models.
|
|
5
5
|
Author: D.A. Brakenhoff
|
|
6
6
|
Maintainer-email: "D.A. Brakenhoff" <d.brakenhoff@artesia-water.nl>, "R. Calje" <r.calje@artesia-water.nl>, "M.A. Vonk" <m.vonk@artesia-water.nl>
|
|
@@ -49,48 +49,49 @@ Classifier: Topic :: Scientific/Engineering :: Hydrology
|
|
|
49
49
|
Requires-Python: >=3.7
|
|
50
50
|
Description-Content-Type: text/markdown
|
|
51
51
|
License-File: LICENSE
|
|
52
|
-
Requires-Dist: pastas
|
|
53
|
-
Requires-Dist: tqdm
|
|
52
|
+
Requires-Dist: pastas>=0.13
|
|
53
|
+
Requires-Dist: tqdm>=4.36
|
|
54
54
|
Requires-Dist: pyyaml
|
|
55
|
-
Provides-Extra: arcticdb
|
|
56
|
-
Requires-Dist: arcticdb ; extra == 'arcticdb'
|
|
57
|
-
Provides-Extra: docs
|
|
58
|
-
Requires-Dist: pastastore[optional] ; extra == 'docs'
|
|
59
|
-
Requires-Dist: sphinx-rtd-theme ; extra == 'docs'
|
|
60
|
-
Requires-Dist: Ipython ; extra == 'docs'
|
|
61
|
-
Requires-Dist: ipykernel ; extra == 'docs'
|
|
62
|
-
Requires-Dist: nbsphinx ; extra == 'docs'
|
|
63
|
-
Requires-Dist: nbsphinx-link ; extra == 'docs'
|
|
64
|
-
Provides-Extra: extensions
|
|
65
|
-
Requires-Dist: hydropandas ; extra == 'extensions'
|
|
66
55
|
Provides-Extra: full
|
|
67
|
-
Requires-Dist: pastastore[arcticdb,optional]
|
|
68
|
-
|
|
69
|
-
|
|
56
|
+
Requires-Dist: pastastore[arcticdb,optional]; extra == "full"
|
|
57
|
+
Requires-Dist: hydropandas; extra == "full"
|
|
58
|
+
Provides-Extra: extensions
|
|
59
|
+
Requires-Dist: hydropandas; extra == "extensions"
|
|
70
60
|
Provides-Extra: optional
|
|
71
|
-
Requires-Dist: contextily
|
|
72
|
-
Requires-Dist: pyproj
|
|
73
|
-
Requires-Dist: adjustText
|
|
61
|
+
Requires-Dist: contextily; extra == "optional"
|
|
62
|
+
Requires-Dist: pyproj; extra == "optional"
|
|
63
|
+
Requires-Dist: adjustText; extra == "optional"
|
|
64
|
+
Provides-Extra: arcticdb
|
|
65
|
+
Requires-Dist: arcticdb; extra == "arcticdb"
|
|
66
|
+
Provides-Extra: lint
|
|
67
|
+
Requires-Dist: ruff; extra == "lint"
|
|
74
68
|
Provides-Extra: test
|
|
75
|
-
Requires-Dist: pastastore[arcticdb,lint,optional]
|
|
76
|
-
Requires-Dist: hydropandas[full]
|
|
77
|
-
Requires-Dist: coverage
|
|
78
|
-
Requires-Dist: codecov
|
|
79
|
-
Requires-Dist: pytest
|
|
80
|
-
Requires-Dist: pytest-cov
|
|
81
|
-
Requires-Dist: pytest-dependency
|
|
82
|
-
Requires-Dist: pytest-benchmark
|
|
83
|
-
Requires-Dist: codacy-coverage
|
|
84
|
-
Provides-Extra:
|
|
85
|
-
Requires-Dist: pastastore[lint,optional]
|
|
86
|
-
Requires-Dist: hydropandas[full]
|
|
87
|
-
Requires-Dist: coverage
|
|
88
|
-
Requires-Dist: codecov
|
|
89
|
-
Requires-Dist: pytest
|
|
90
|
-
Requires-Dist: pytest-cov
|
|
91
|
-
Requires-Dist: pytest-dependency
|
|
92
|
-
Requires-Dist: pytest-benchmark
|
|
93
|
-
Requires-Dist: codacy-coverage
|
|
69
|
+
Requires-Dist: pastastore[arcticdb,lint,optional]; extra == "test"
|
|
70
|
+
Requires-Dist: hydropandas[full]; extra == "test"
|
|
71
|
+
Requires-Dist: coverage; extra == "test"
|
|
72
|
+
Requires-Dist: codecov; extra == "test"
|
|
73
|
+
Requires-Dist: pytest; extra == "test"
|
|
74
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
75
|
+
Requires-Dist: pytest-dependency; extra == "test"
|
|
76
|
+
Requires-Dist: pytest-benchmark; extra == "test"
|
|
77
|
+
Requires-Dist: codacy-coverage; extra == "test"
|
|
78
|
+
Provides-Extra: test-py312
|
|
79
|
+
Requires-Dist: pastastore[lint,optional]; extra == "test-py312"
|
|
80
|
+
Requires-Dist: hydropandas[full]; extra == "test-py312"
|
|
81
|
+
Requires-Dist: coverage; extra == "test-py312"
|
|
82
|
+
Requires-Dist: codecov; extra == "test-py312"
|
|
83
|
+
Requires-Dist: pytest; extra == "test-py312"
|
|
84
|
+
Requires-Dist: pytest-cov; extra == "test-py312"
|
|
85
|
+
Requires-Dist: pytest-dependency; extra == "test-py312"
|
|
86
|
+
Requires-Dist: pytest-benchmark; extra == "test-py312"
|
|
87
|
+
Requires-Dist: codacy-coverage; extra == "test-py312"
|
|
88
|
+
Provides-Extra: docs
|
|
89
|
+
Requires-Dist: pastastore[optional]; extra == "docs"
|
|
90
|
+
Requires-Dist: sphinx_rtd_theme; extra == "docs"
|
|
91
|
+
Requires-Dist: Ipython; extra == "docs"
|
|
92
|
+
Requires-Dist: ipykernel; extra == "docs"
|
|
93
|
+
Requires-Dist: nbsphinx; extra == "docs"
|
|
94
|
+
Requires-Dist: nbsphinx_link; extra == "docs"
|
|
94
95
|
|
|
95
96
|

|
|
96
97
|
[](https://pastastore.readthedocs.io/en/latest/?badge=latest)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
docs/conf.py,sha256=XcZUTmn9fGDhhu8k3mpaLu435SpIRNpABADCCTJJuag,6291
|
|
2
|
+
pastastore/__init__.py,sha256=cWwG9-YeiI4aOU0CDBGKbQgmKmmkcPd64YwPq2rRGt0,416
|
|
3
|
+
pastastore/base.py,sha256=hOvkgACew4fpLWumLfHA6PrxLDH1EvqdWjEvFbmxJR0,46436
|
|
4
|
+
pastastore/connectors.py,sha256=QlaFcVEM_ZtOgLd3M2yZfgogcw0zNM08pVbnyRS3Mr8,48454
|
|
5
|
+
pastastore/datasets.py,sha256=FHVfmKqb8beEs9NONsWrCoJY37BmlvFLSEQ1VAFmE8A,6415
|
|
6
|
+
pastastore/plotting.py,sha256=t6gEeHVGzrwvM6q1l8V3OkklpU75O2Y4h6nKEHRWdjo,46416
|
|
7
|
+
pastastore/store.py,sha256=HZtof9gIFSW2nQpc5FHMPb1RTjgo-QzIJxueywd4jDA,65840
|
|
8
|
+
pastastore/styling.py,sha256=4xAY0FmhKrvmAGIuoMM7Uucww_X4KAxTpEoHlsxMldc,2280
|
|
9
|
+
pastastore/util.py,sha256=KCUFV4GkocWaRpG57CdxzfkTXyTEpPjnxsKehYPVN7U,28249
|
|
10
|
+
pastastore/version.py,sha256=vuqYDMX5ua14OQP04vqXH_0A_Ra2XErriiNPxgZEc5w,1205
|
|
11
|
+
pastastore/yaml_interface.py,sha256=MddELxWe8_aqJRMUydOCbjoU1-ZodzxFKYnAaqJ5SqA,29947
|
|
12
|
+
pastastore/extensions/__init__.py,sha256=lCN9xfX1qefUzUbE2FQ12c6NjLbf5HoNo-D8cGb5CTw,461
|
|
13
|
+
pastastore/extensions/accessor.py,sha256=kftQM6dqMDoySbyTKcvmkjC5gJRp465KA18G4NVXUO0,367
|
|
14
|
+
pastastore/extensions/hpd.py,sha256=fcXWb3BlWlogCbg7a2Gmha8P_eCh6zSGTyRlYp3mjXA,27466
|
|
15
|
+
tests/conftest.py,sha256=u097z7LGAnviuzXPzvER9oPjsZWqdij1CJLnW_sPY8E,5258
|
|
16
|
+
tests/test_001_import.py,sha256=g8AaJzWZ088A4B30_w-MrDfAVeeg8m78l--j7Onsklc,208
|
|
17
|
+
tests/test_002_connectors.py,sha256=k9etSRuSFVOrSEtZyxqsCF9GwIg0T7VdDJ2SjSe6i_s,7742
|
|
18
|
+
tests/test_003_pastastore.py,sha256=2nC0pU478iRbYKnVVSjh5F6PA_7SvFROwD6SABL2YSE,9370
|
|
19
|
+
tests/test_004_yaml.py,sha256=3hMNjb9s0S2rbmpyEjW6FDRAxfUZS_U1qoPl4wB-cCo,4440
|
|
20
|
+
tests/test_005_maps_plots.py,sha256=L0ppGf-cudsrdxteWy3qsV4We96DW4bCBE7c6jEm6aM,1866
|
|
21
|
+
tests/test_006_benchmark.py,sha256=yuExF35qqxhw04uYMH3OIOlGr71c4AJSJDMjGD8GefY,4983
|
|
22
|
+
tests/test_007_hpdextension.py,sha256=1QNUahq3hzqxjKbzsjofi9Yuyqe_oDGL0vWp6iouYe4,3004
|
|
23
|
+
tests/test_008_stressmodels.py,sha256=733fyCvuzjKcaLjvSMt5dTTLp-T4alzNJAToSxTIUug,4003
|
|
24
|
+
pastastore-1.8.0.dist-info/LICENSE,sha256=DtHftfUEm99KzgwLr3rQUTg8H3kAS0Z-p5WWJgLf_OY,1082
|
|
25
|
+
pastastore-1.8.0.dist-info/METADATA,sha256=nWFELMkHg9yfp76Ib1xlnPdrp7RZh-9KyhW3CO3rOVY,8032
|
|
26
|
+
pastastore-1.8.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
|
27
|
+
pastastore-1.8.0.dist-info/top_level.txt,sha256=1bgyMk1p23f04RK83Jju2_YAQBwyoQD_fInxoPB4YRw,22
|
|
28
|
+
pastastore-1.8.0.dist-info/RECORD,,
|