pyhdf5-handler 0.6__tar.gz → 0.8__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.
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/PKG-INFO +24 -1
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/README.md +23 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/Release_note.txt +11 -0
- pyhdf5_handler-0.8/mycontrol.hdf5 +0 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/pyhdf5_handler/__init__.py +3 -1
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/pyhdf5_handler/src/__init__.py +1 -0
- pyhdf5_handler-0.8/pyhdf5_handler/src/constant.py +3 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/pyhdf5_handler/src/hdf5_handler.py +174 -24
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/pyhdf5_handler/src/object_handler.py +207 -79
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/pyhdf5_handler/tutorial/hdf5_io_tests.py +87 -10
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/pyproject.toml +1 -1
- pyhdf5_handler-0.6/test.hdf5 +0 -0
- pyhdf5_handler-0.6/test_fichier_julie.py +0 -42
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/.spyproject/config/backups/codestyle.ini.bak +0 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/.spyproject/config/backups/encoding.ini.bak +0 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/.spyproject/config/backups/vcs.ini.bak +0 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/.spyproject/config/backups/workspace.ini.bak +0 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/.spyproject/config/codestyle.ini +0 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/.spyproject/config/defaults/defaults-codestyle-0.2.0.ini +0 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/.spyproject/config/defaults/defaults-encoding-0.2.0.ini +0 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/.spyproject/config/defaults/defaults-vcs-0.2.0.ini +0 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/.spyproject/config/defaults/defaults-workspace-0.2.0.ini +0 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/.spyproject/config/encoding.ini +0 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/.spyproject/config/vcs.ini +0 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/.spyproject/config/workspace.ini +0 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/LICENSE +0 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/pyhdf5_handler/tutorial/__init__.py +0 -0
- {pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/pyhdf5_handler/tutorial/complementary_test.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyhdf5_handler
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8
|
|
4
4
|
Summary: A Python library to read and write data to HDF5 format. This library is based on the h5py (https://docs.h5py.org/en/stable/index.html) and has been developed by Maxime Jay-Allemand at Hydris hydrologie (https://www.hydris-hydrologie.fr/)
|
|
5
5
|
Project-URL: Homepage, https://codeberg.org/maximejay/pyhdf5_handler
|
|
6
6
|
Project-URL: Issues, https://codeberg.org/maximejay/pyhdf5_handler/issues
|
|
@@ -169,6 +169,29 @@ pyhdf5_handler.save_dict_to_hdf5file(
|
|
|
169
169
|
)
|
|
170
170
|
```
|
|
171
171
|
|
|
172
|
+
# Exclude object type
|
|
173
|
+
|
|
174
|
+
Many python object are very complex and huge and there is no reason to parse and save it into an hdf5file. Pyhdf5_handler may crash handling such python object like geopandas.GeoDataFrame or shapely.Polygon. These module, geopandas and shapely, are excluded. To exclude other modules, you may use the global constant variable `pyhdf5_handler.EXCLUDE_PYTHON_OBJ`. The key will be keept, but the dataset will contain a string with the mention "excluded data type <class 'shapely.geometry.polygon.Polygon'>".
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
pyhdf5_handler.EXCLUDE_PYTHON_OBJ
|
|
178
|
+
['geopandas', 'shapely']
|
|
179
|
+
pyhdf5_handler.EXCLUDE_PYTHON_OBJ.append("numpy") # will exclude numpy also
|
|
180
|
+
mydict = {
|
|
181
|
+
"g": geopandas.GeoDataFrame(),
|
|
182
|
+
"s": shapely.Polygon(),
|
|
183
|
+
"n_exclude": np.zeros(0),
|
|
184
|
+
}
|
|
185
|
+
pyhdf5_handler.save_dict_to_hdf5file("./test.hdf5", mydict)
|
|
186
|
+
pyhdf5_handler.get_hdf5file_item(
|
|
187
|
+
path_to_hdf5="./test.hdf5",
|
|
188
|
+
location="./",
|
|
189
|
+
item="n_exclude",
|
|
190
|
+
search_attrs=False,
|
|
191
|
+
)
|
|
192
|
+
["excluded data type <class 'numpy.ndarray'>"]
|
|
193
|
+
```
|
|
194
|
+
|
|
172
195
|
#### Viewing the content of an HDF5 file
|
|
173
196
|
|
|
174
197
|
Two methods can be used to view the content of an hdf5 file. The method `pyhdf5_handler.src.hdf5_handler.hdf5file_view` print the full recursive arborescence of an hdf5 file, including dataset and attribute:
|
|
@@ -152,6 +152,29 @@ pyhdf5_handler.save_dict_to_hdf5file(
|
|
|
152
152
|
)
|
|
153
153
|
```
|
|
154
154
|
|
|
155
|
+
# Exclude object type
|
|
156
|
+
|
|
157
|
+
Many python object are very complex and huge and there is no reason to parse and save it into an hdf5file. Pyhdf5_handler may crash handling such python object like geopandas.GeoDataFrame or shapely.Polygon. These module, geopandas and shapely, are excluded. To exclude other modules, you may use the global constant variable `pyhdf5_handler.EXCLUDE_PYTHON_OBJ`. The key will be keept, but the dataset will contain a string with the mention "excluded data type <class 'shapely.geometry.polygon.Polygon'>".
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
pyhdf5_handler.EXCLUDE_PYTHON_OBJ
|
|
161
|
+
['geopandas', 'shapely']
|
|
162
|
+
pyhdf5_handler.EXCLUDE_PYTHON_OBJ.append("numpy") # will exclude numpy also
|
|
163
|
+
mydict = {
|
|
164
|
+
"g": geopandas.GeoDataFrame(),
|
|
165
|
+
"s": shapely.Polygon(),
|
|
166
|
+
"n_exclude": np.zeros(0),
|
|
167
|
+
}
|
|
168
|
+
pyhdf5_handler.save_dict_to_hdf5file("./test.hdf5", mydict)
|
|
169
|
+
pyhdf5_handler.get_hdf5file_item(
|
|
170
|
+
path_to_hdf5="./test.hdf5",
|
|
171
|
+
location="./",
|
|
172
|
+
item="n_exclude",
|
|
173
|
+
search_attrs=False,
|
|
174
|
+
)
|
|
175
|
+
["excluded data type <class 'numpy.ndarray'>"]
|
|
176
|
+
```
|
|
177
|
+
|
|
155
178
|
#### Viewing the content of an HDF5 file
|
|
156
179
|
|
|
157
180
|
Two methods can be used to view the content of an hdf5 file. The method `pyhdf5_handler.src.hdf5_handler.hdf5file_view` print the full recursive arborescence of an hdf5 file, including dataset and attribute:
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
v0.8 : 19-06-2026
|
|
2
|
+
- relase 0.8
|
|
3
|
+
- Add support for pd.DataFrame()
|
|
4
|
+
- improve function map_dict_to_object
|
|
5
|
+
- Fix : return in hdf5_dataset_creator after parsing an unknown object
|
|
6
|
+
- Add function to map a dictionary to an object with a given structure
|
|
7
|
+
|
|
8
|
+
v0.7 : 12-03-2026
|
|
9
|
+
- Exclude some python object when parsing a dict or an object. For instance Geopandas and shapely are excluded, because pyhdf5_handler crash when handled these complex python object. Other module can be exclude using the global variable EXCLUDE_PYTHON_OBJ.
|
|
10
|
+
- Fix: Max recursion counter was set to zeros at the begining of the recursive function.
|
|
11
|
+
|
|
1
12
|
v0.6 : 11-02-2026
|
|
2
13
|
- Fix : handle np.int64/np.float64 type like. Pyhdf5_handler will correctly return unique float or int stored in a dataset.
|
|
3
14
|
|
|
Binary file
|
|
@@ -4,4 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
from .src.hdf5_handler import close_all_hdf5_file, open_hdf5, add_hdf5_sub_group, hdf5_dataset_creator, save_dict_to_hdf5, save_dict_to_hdf5file, save_object_to_hdf5file, read_hdf5file_as_dict, read_hdf5_as_dict, hdf5_read_dataset, get_hdf5file_attribute, get_hdf5file_dataset, get_hdf5file_item, get_hdf5_item, search_in_hdf5file, search_in_hdf5, hdf5file_view, hdf5file_ls, hdf5_ls, hdf5_view
|
|
6
6
|
|
|
7
|
-
from .src.object_handler import generate_dict_structure, generate_object_structure, read_object_as_dict
|
|
7
|
+
from .src.object_handler import generate_dict_structure, generate_object_structure, read_object_as_dict, map_dict_to_object
|
|
8
|
+
|
|
9
|
+
from .src.constant import EXCLUDE_PYTHON_OBJ
|
|
@@ -10,6 +10,8 @@ import time
|
|
|
10
10
|
import importlib
|
|
11
11
|
|
|
12
12
|
from ..src import object_handler
|
|
13
|
+
from ..src import constant
|
|
14
|
+
|
|
13
15
|
import gc
|
|
14
16
|
import re
|
|
15
17
|
|
|
@@ -97,7 +99,9 @@ def open_hdf5(path, read_only=False, replace=False, wait_time=0):
|
|
|
97
99
|
print(f"File {path} does not exist.")
|
|
98
100
|
return f
|
|
99
101
|
else:
|
|
100
|
-
print(
|
|
102
|
+
print(
|
|
103
|
+
f"The file {path} is unvailable, waiting {wait}/{wait_time}s"
|
|
104
|
+
)
|
|
101
105
|
|
|
102
106
|
wait = wait + 1
|
|
103
107
|
|
|
@@ -214,13 +218,19 @@ def _dump_object_to_hdf5_from_dict_attribute(hdf5, instance, dict_attr):
|
|
|
214
218
|
sub_instance = instance
|
|
215
219
|
|
|
216
220
|
if isinstance(value, dict):
|
|
217
|
-
_dump_object_to_hdf5_from_dict_attribute(
|
|
221
|
+
_dump_object_to_hdf5_from_dict_attribute(
|
|
222
|
+
hdf5[attr], sub_instance, value
|
|
223
|
+
)
|
|
218
224
|
|
|
219
225
|
elif isinstance(value, list):
|
|
220
|
-
_dump_object_to_hdf5_from_list_attribute(
|
|
226
|
+
_dump_object_to_hdf5_from_list_attribute(
|
|
227
|
+
hdf5[attr], sub_instance, value
|
|
228
|
+
)
|
|
221
229
|
|
|
222
230
|
elif isinstance(value, str):
|
|
223
|
-
_dump_object_to_hdf5_from_str_attribute(
|
|
231
|
+
_dump_object_to_hdf5_from_str_attribute(
|
|
232
|
+
hdf5[attr], sub_instance, value
|
|
233
|
+
)
|
|
224
234
|
|
|
225
235
|
else:
|
|
226
236
|
|
|
@@ -390,6 +400,25 @@ def _hdf5_handle_DatetimeIndex(name: str, value: pd.DatetimeIndex):
|
|
|
390
400
|
return dataset
|
|
391
401
|
|
|
392
402
|
|
|
403
|
+
def _hdf5_handle_PandaDataFrame(
|
|
404
|
+
hdf5: h5py.File, name: str, value: pd.DataFrame
|
|
405
|
+
):
|
|
406
|
+
|
|
407
|
+
hdf5 = add_hdf5_sub_group(hdf5, subgroup=name)
|
|
408
|
+
hdf5_data = hdf5[name]
|
|
409
|
+
|
|
410
|
+
hdf5_data = add_hdf5_sub_group(hdf5_data, subgroup="pd_DataFrame")
|
|
411
|
+
hdf5_data = hdf5_data["pd_DataFrame"]
|
|
412
|
+
|
|
413
|
+
keys = _hdf5_handle_array("columns", np.array(list(value.columns)))
|
|
414
|
+
_hdf5_create_dataset(hdf5_data, keys)
|
|
415
|
+
|
|
416
|
+
dataset = _hdf5_handle_array("array", value.to_numpy())
|
|
417
|
+
_hdf5_create_dataset(hdf5_data, dataset)
|
|
418
|
+
|
|
419
|
+
return
|
|
420
|
+
|
|
421
|
+
|
|
393
422
|
def _hdf5_handle_list(name: str, value: list | tuple):
|
|
394
423
|
|
|
395
424
|
arr = np.array(value)
|
|
@@ -399,6 +428,32 @@ def _hdf5_handle_list(name: str, value: list | tuple):
|
|
|
399
428
|
return dataset
|
|
400
429
|
|
|
401
430
|
|
|
431
|
+
def _hdf5_handle_exclude_obj(name: str, value: list | tuple):
|
|
432
|
+
|
|
433
|
+
dtype = type(value)
|
|
434
|
+
|
|
435
|
+
dataset = {
|
|
436
|
+
"name": name,
|
|
437
|
+
"attr_value": str(dtype),
|
|
438
|
+
"dataset_value": f"excluded data type {str(dtype)}",
|
|
439
|
+
"shape": 1,
|
|
440
|
+
"dtype": h5py.string_dtype(encoding="utf-8"),
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
return dataset
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
def _hdf5_skip_cls(value):
|
|
447
|
+
|
|
448
|
+
type_str = str(type(value))
|
|
449
|
+
module_name = type_str.split("'")[1].split(".")[0]
|
|
450
|
+
|
|
451
|
+
if module_name in constant.EXCLUDE_PYTHON_OBJ:
|
|
452
|
+
return True
|
|
453
|
+
else:
|
|
454
|
+
return False
|
|
455
|
+
|
|
456
|
+
|
|
402
457
|
def _hdf5_handle_array(name: str, value: np.ndarray):
|
|
403
458
|
|
|
404
459
|
dtype_attr = type(value)
|
|
@@ -477,8 +532,11 @@ def hdf5_dataset_creator(hdf5: h5py.File, name: str, value):
|
|
|
477
532
|
value to write in the hdf5
|
|
478
533
|
|
|
479
534
|
"""
|
|
480
|
-
|
|
481
|
-
if
|
|
535
|
+
|
|
536
|
+
if _hdf5_skip_cls(value):
|
|
537
|
+
dataset = _hdf5_handle_exclude_obj(name, value)
|
|
538
|
+
|
|
539
|
+
elif isinstance(value, str):
|
|
482
540
|
dataset = _hdf5_handle_str(name, value)
|
|
483
541
|
|
|
484
542
|
elif isinstance(value, numbers.Number):
|
|
@@ -493,6 +551,12 @@ def hdf5_dataset_creator(hdf5: h5py.File, name: str, value):
|
|
|
493
551
|
elif isinstance(value, pd.DatetimeIndex):
|
|
494
552
|
dataset = _hdf5_handle_DatetimeIndex(name, value)
|
|
495
553
|
|
|
554
|
+
# TODO : To be tested
|
|
555
|
+
elif isinstance(value, pd.DataFrame):
|
|
556
|
+
|
|
557
|
+
_hdf5_handle_PandaDataFrame(hdf5, name, value)
|
|
558
|
+
return
|
|
559
|
+
|
|
496
560
|
elif isinstance(value, list):
|
|
497
561
|
dataset = _hdf5_handle_list(name, value)
|
|
498
562
|
|
|
@@ -515,6 +579,8 @@ def hdf5_dataset_creator(hdf5: h5py.File, name: str, value):
|
|
|
515
579
|
|
|
516
580
|
save_dict_to_hdf5(hdf5[name], newdict)
|
|
517
581
|
|
|
582
|
+
return
|
|
583
|
+
|
|
518
584
|
_hdf5_create_dataset(hdf5, dataset)
|
|
519
585
|
|
|
520
586
|
|
|
@@ -572,6 +638,34 @@ def _dump_ndarray_to_hdf5(hdf5, value):
|
|
|
572
638
|
)
|
|
573
639
|
|
|
574
640
|
|
|
641
|
+
def _read_pd_dataframe(hdf5):
|
|
642
|
+
"""
|
|
643
|
+
read a pandas dataframe data structure from hdf5 file
|
|
644
|
+
|
|
645
|
+
Parameters
|
|
646
|
+
----------
|
|
647
|
+
|
|
648
|
+
hdf5 : h5py.File
|
|
649
|
+
an hdf5 object at the roots of the ndarray datastructure
|
|
650
|
+
|
|
651
|
+
Return
|
|
652
|
+
------
|
|
653
|
+
|
|
654
|
+
pd.DataFrame : the pandas dataframe
|
|
655
|
+
|
|
656
|
+
"""
|
|
657
|
+
|
|
658
|
+
if "pd_DataFrame" in list(hdf5.keys()):
|
|
659
|
+
columns = hdf5["pd_DataFrame/columns"][:]
|
|
660
|
+
array = hdf5["pd_DataFrame/array"][:]
|
|
661
|
+
|
|
662
|
+
newdict = {}
|
|
663
|
+
for i, col in enumerate(columns):
|
|
664
|
+
newdict.update({col.decode(): array[:, i]})
|
|
665
|
+
|
|
666
|
+
return pd.DataFrame(newdict)
|
|
667
|
+
|
|
668
|
+
|
|
575
669
|
def _read_ndarray_datastructure(hdf5):
|
|
576
670
|
"""
|
|
577
671
|
read a ndarray data structure from hdf5 file
|
|
@@ -826,7 +920,11 @@ def save_object_to_hdf5file(
|
|
|
826
920
|
|
|
827
921
|
|
|
828
922
|
def read_hdf5file_as_dict(
|
|
829
|
-
path_to_hdf5,
|
|
923
|
+
path_to_hdf5,
|
|
924
|
+
location="./",
|
|
925
|
+
wait_time=0,
|
|
926
|
+
read_attrs=True,
|
|
927
|
+
read_dataset_attrs=False,
|
|
830
928
|
):
|
|
831
929
|
"""
|
|
832
930
|
|
|
@@ -868,7 +966,9 @@ def read_hdf5file_as_dict(
|
|
|
868
966
|
return None
|
|
869
967
|
|
|
870
968
|
dictionary = read_hdf5_as_dict(
|
|
871
|
-
hdf5[location],
|
|
969
|
+
hdf5[location],
|
|
970
|
+
read_attrs=read_attrs,
|
|
971
|
+
read_dataset_attrs=read_dataset_attrs,
|
|
872
972
|
)
|
|
873
973
|
|
|
874
974
|
hdf5.close()
|
|
@@ -907,7 +1007,9 @@ def read_hdf5_as_dict(hdf5, read_attrs=True, read_dataset_attrs=False):
|
|
|
907
1007
|
|
|
908
1008
|
"""
|
|
909
1009
|
|
|
910
|
-
if not isinstance(
|
|
1010
|
+
if not isinstance(
|
|
1011
|
+
hdf5, (h5py.File, h5py.Group, h5py.Dataset, h5py.Datatype)
|
|
1012
|
+
):
|
|
911
1013
|
print("Error: input arg is not an instance of hdf5.File()")
|
|
912
1014
|
return {}
|
|
913
1015
|
|
|
@@ -920,7 +1022,12 @@ def read_hdf5_as_dict(hdf5, read_attrs=True, read_dataset_attrs=False):
|
|
|
920
1022
|
if key == "ndarray_ds":
|
|
921
1023
|
|
|
922
1024
|
# dictionary.update({key: _read_ndarray_datastructure(hdf5)})
|
|
923
|
-
|
|
1025
|
+
values = _read_ndarray_datastructure(hdf5)
|
|
1026
|
+
dictionary.update({key: values})
|
|
1027
|
+
|
|
1028
|
+
elif key == "pd_DataFrame":
|
|
1029
|
+
values = _read_pd_dataframe(hdf5)
|
|
1030
|
+
dictionary.update({key: values})
|
|
924
1031
|
|
|
925
1032
|
else:
|
|
926
1033
|
|
|
@@ -941,14 +1048,17 @@ def read_hdf5_as_dict(hdf5, read_attrs=True, read_dataset_attrs=False):
|
|
|
941
1048
|
list_attribute = []
|
|
942
1049
|
if read_attrs or read_dataset_attrs:
|
|
943
1050
|
tmp_list_attribute = list(hdf5.attrs.keys())
|
|
944
|
-
hdf5_item_matching_attributes = [
|
|
1051
|
+
hdf5_item_matching_attributes = [
|
|
1052
|
+
"_" + element for element in list(hdf5.keys())
|
|
1053
|
+
]
|
|
945
1054
|
|
|
946
1055
|
if read_attrs:
|
|
947
1056
|
|
|
948
1057
|
list_attribute.extend(
|
|
949
1058
|
list(
|
|
950
1059
|
filter(
|
|
951
|
-
lambda l: l not in hdf5_item_matching_attributes,
|
|
1060
|
+
lambda l: l not in hdf5_item_matching_attributes,
|
|
1061
|
+
tmp_list_attribute,
|
|
952
1062
|
)
|
|
953
1063
|
)
|
|
954
1064
|
)
|
|
@@ -956,7 +1066,12 @@ def read_hdf5_as_dict(hdf5, read_attrs=True, read_dataset_attrs=False):
|
|
|
956
1066
|
if read_dataset_attrs:
|
|
957
1067
|
|
|
958
1068
|
list_attribute.extend(
|
|
959
|
-
list(
|
|
1069
|
+
list(
|
|
1070
|
+
filter(
|
|
1071
|
+
lambda l: l in hdf5_item_matching_attributes,
|
|
1072
|
+
tmp_list_attribute,
|
|
1073
|
+
)
|
|
1074
|
+
)
|
|
960
1075
|
)
|
|
961
1076
|
|
|
962
1077
|
for key in list_attribute:
|
|
@@ -1065,7 +1180,11 @@ def hdf5_read_dataset(item, expected_type=None):
|
|
|
1065
1180
|
|
|
1066
1181
|
values = None
|
|
1067
1182
|
|
|
1068
|
-
elif expected_type in (
|
|
1183
|
+
elif expected_type in (
|
|
1184
|
+
str(pd.Timestamp),
|
|
1185
|
+
str(np.datetime64),
|
|
1186
|
+
str(datetime.datetime),
|
|
1187
|
+
):
|
|
1069
1188
|
|
|
1070
1189
|
if expected_type == str(pd.Timestamp):
|
|
1071
1190
|
values = pd.Timestamp(item[0].decode())
|
|
@@ -1149,7 +1268,9 @@ def get_hdf5file_attribute(
|
|
|
1149
1268
|
return return_attribute
|
|
1150
1269
|
|
|
1151
1270
|
|
|
1152
|
-
def get_hdf5file_dataset(
|
|
1271
|
+
def get_hdf5file_dataset(
|
|
1272
|
+
path_to_hdf5=str(), location="./", dataset=None, wait_time=0
|
|
1273
|
+
):
|
|
1153
1274
|
"""
|
|
1154
1275
|
Get the value of an attribute in the hdf5file
|
|
1155
1276
|
|
|
@@ -1201,7 +1322,11 @@ def get_hdf5file_dataset(path_to_hdf5=str(), location="./", dataset=None, wait_t
|
|
|
1201
1322
|
|
|
1202
1323
|
|
|
1203
1324
|
def get_hdf5file_item(
|
|
1204
|
-
path_to_hdf5=str(),
|
|
1325
|
+
path_to_hdf5=str(),
|
|
1326
|
+
location="./",
|
|
1327
|
+
item=None,
|
|
1328
|
+
wait_time=0,
|
|
1329
|
+
search_attrs=False,
|
|
1205
1330
|
):
|
|
1206
1331
|
"""
|
|
1207
1332
|
|
|
@@ -1244,7 +1369,10 @@ def get_hdf5file_item(
|
|
|
1244
1369
|
return None
|
|
1245
1370
|
|
|
1246
1371
|
hdf5_item = get_hdf5_item(
|
|
1247
|
-
hdf5_instance=hdf5,
|
|
1372
|
+
hdf5_instance=hdf5,
|
|
1373
|
+
location=location,
|
|
1374
|
+
item=item,
|
|
1375
|
+
search_attrs=search_attrs,
|
|
1248
1376
|
)
|
|
1249
1377
|
|
|
1250
1378
|
hdf5.close()
|
|
@@ -1252,7 +1380,9 @@ def get_hdf5file_item(
|
|
|
1252
1380
|
return hdf5_item
|
|
1253
1381
|
|
|
1254
1382
|
|
|
1255
|
-
def get_hdf5_item(
|
|
1383
|
+
def get_hdf5_item(
|
|
1384
|
+
hdf5_instance=None, location="./", item=None, search_attrs=False
|
|
1385
|
+
):
|
|
1256
1386
|
"""
|
|
1257
1387
|
|
|
1258
1388
|
Get a custom item in an hdf5file
|
|
@@ -1320,6 +1450,10 @@ def get_hdf5_item(hdf5_instance=None, location="./", item=None, search_attrs=Fal
|
|
|
1320
1450
|
|
|
1321
1451
|
return _read_ndarray_datastructure(hdf5)
|
|
1322
1452
|
|
|
1453
|
+
elif item == "pd_DataFrame":
|
|
1454
|
+
|
|
1455
|
+
return _read_pd_dataframe(hdf5)
|
|
1456
|
+
|
|
1323
1457
|
else:
|
|
1324
1458
|
|
|
1325
1459
|
returned_dict = read_hdf5_as_dict(hdf5_item)
|
|
@@ -1391,7 +1525,9 @@ def search_in_hdf5file(
|
|
|
1391
1525
|
if hdf5 is None:
|
|
1392
1526
|
return None
|
|
1393
1527
|
|
|
1394
|
-
results = search_in_hdf5(
|
|
1528
|
+
results = search_in_hdf5(
|
|
1529
|
+
hdf5, key, location=location, search_attrs=search_attrs
|
|
1530
|
+
)
|
|
1395
1531
|
|
|
1396
1532
|
hdf5.close()
|
|
1397
1533
|
|
|
@@ -1513,7 +1649,12 @@ def search_in_hdf5(hdf5_base, key=None, location="./", search_attrs=False):
|
|
|
1513
1649
|
values = item[:]
|
|
1514
1650
|
|
|
1515
1651
|
result.append(
|
|
1516
|
-
{
|
|
1652
|
+
{
|
|
1653
|
+
"path": location,
|
|
1654
|
+
"key": key,
|
|
1655
|
+
"datatype": "dataset",
|
|
1656
|
+
"value": values,
|
|
1657
|
+
}
|
|
1517
1658
|
)
|
|
1518
1659
|
|
|
1519
1660
|
return result
|
|
@@ -1745,14 +1886,17 @@ def hdf5_view(
|
|
|
1745
1886
|
list_attribute = []
|
|
1746
1887
|
if list_attrs or list_dataset_attrs:
|
|
1747
1888
|
tmp_list_attribute = list(hdf5.attrs.keys())
|
|
1748
|
-
list_keys_matching_attributes = [
|
|
1889
|
+
list_keys_matching_attributes = [
|
|
1890
|
+
"_" + element for element in list(hdf5.keys())
|
|
1891
|
+
]
|
|
1749
1892
|
|
|
1750
1893
|
if list_attrs:
|
|
1751
1894
|
|
|
1752
1895
|
list_attribute.extend(
|
|
1753
1896
|
list(
|
|
1754
1897
|
filter(
|
|
1755
|
-
lambda l: l not in list_keys_matching_attributes,
|
|
1898
|
+
lambda l: l not in list_keys_matching_attributes,
|
|
1899
|
+
tmp_list_attribute,
|
|
1756
1900
|
)
|
|
1757
1901
|
)
|
|
1758
1902
|
)
|
|
@@ -1760,14 +1904,20 @@ def hdf5_view(
|
|
|
1760
1904
|
if list_dataset_attrs:
|
|
1761
1905
|
|
|
1762
1906
|
list_attribute.extend(
|
|
1763
|
-
list(
|
|
1907
|
+
list(
|
|
1908
|
+
filter(
|
|
1909
|
+
lambda l: l in list_keys_matching_attributes,
|
|
1910
|
+
tmp_list_attribute,
|
|
1911
|
+
)
|
|
1912
|
+
)
|
|
1764
1913
|
)
|
|
1765
1914
|
|
|
1766
1915
|
for key in list_attribute:
|
|
1767
1916
|
values = hdf5.attrs[key]
|
|
1768
1917
|
sub_location = os.path.join(location, key)
|
|
1769
1918
|
if isinstance(
|
|
1770
|
-
values,
|
|
1919
|
+
values,
|
|
1920
|
+
(int, float, np.int64, np.float64, np.int32, np.float32, np.bool),
|
|
1771
1921
|
):
|
|
1772
1922
|
result.append(
|
|
1773
1923
|
f"{level_base}| {sub_location}, attribute, type={type(hdf5.attrs[key])}, value={values}"
|
|
@@ -1,41 +1,69 @@
|
|
|
1
|
-
|
|
2
1
|
from __future__ import annotations
|
|
3
2
|
|
|
4
3
|
import numpy as np
|
|
5
4
|
import numbers
|
|
6
5
|
import pandas as pd
|
|
7
6
|
import datetime
|
|
7
|
+
from ..src import constant
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def _isinstance_pandas(value):
|
|
11
|
-
pandas_classes = [
|
|
11
|
+
pandas_classes = [
|
|
12
|
+
getattr(pd, item)
|
|
13
|
+
for item in dir(pd)
|
|
14
|
+
if isinstance(getattr(pd, item), type)
|
|
15
|
+
]
|
|
12
16
|
for cls in pandas_classes:
|
|
13
17
|
if isinstance(value, cls):
|
|
14
18
|
return True
|
|
15
19
|
return False
|
|
16
20
|
|
|
21
|
+
|
|
17
22
|
def _isinstance_numpy(value):
|
|
18
|
-
numpy_classes = [
|
|
23
|
+
numpy_classes = [
|
|
24
|
+
getattr(np, item)
|
|
25
|
+
for item in dir(np)
|
|
26
|
+
if isinstance(getattr(np, item), type)
|
|
27
|
+
]
|
|
19
28
|
for cls in numpy_classes:
|
|
20
29
|
if isinstance(value, cls):
|
|
21
30
|
return True
|
|
22
31
|
return False
|
|
23
32
|
|
|
33
|
+
|
|
24
34
|
def _isinstance_datetime(value):
|
|
25
|
-
datetime_classes = [
|
|
35
|
+
datetime_classes = [
|
|
36
|
+
getattr(datetime, item)
|
|
37
|
+
for item in dir(datetime)
|
|
38
|
+
if isinstance(getattr(datetime, item), type)
|
|
39
|
+
]
|
|
26
40
|
for cls in datetime_classes:
|
|
27
41
|
if isinstance(value, cls):
|
|
28
42
|
return True
|
|
29
43
|
return False
|
|
30
44
|
|
|
31
|
-
|
|
45
|
+
|
|
46
|
+
def _isinstance_exclude_obj(value):
|
|
47
|
+
|
|
48
|
+
type_str = str(type(value))
|
|
49
|
+
module_name = type_str.split("'")[1].split(".")[0]
|
|
50
|
+
|
|
51
|
+
if module_name in constant.EXCLUDE_PYTHON_OBJ:
|
|
52
|
+
return True
|
|
53
|
+
else:
|
|
54
|
+
return False
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def generate_dict_structure(
|
|
58
|
+
dictionary, recursion_counter=0, recursion_limit=100, include_method=True
|
|
59
|
+
):
|
|
32
60
|
"""
|
|
33
|
-
|
|
61
|
+
|
|
34
62
|
this function create a full dictionnary containing all the structure of an dictionnary in order to save it to an hdf5
|
|
35
63
|
|
|
36
64
|
Parameters
|
|
37
65
|
----------
|
|
38
|
-
|
|
66
|
+
|
|
39
67
|
instance : python dictionary
|
|
40
68
|
a custom dictionary.
|
|
41
69
|
recursion_limit : int
|
|
@@ -47,70 +75,148 @@ def generate_dict_structure(dictionary,recursion_counter=0,recursion_limit=100,i
|
|
|
47
75
|
|
|
48
76
|
Returns
|
|
49
77
|
-------
|
|
50
|
-
|
|
78
|
+
|
|
51
79
|
list or dict :
|
|
52
80
|
A list or dictionary matching the structure of the python object.
|
|
53
|
-
|
|
81
|
+
|
|
54
82
|
"""
|
|
55
|
-
key_data={}
|
|
83
|
+
key_data = {}
|
|
56
84
|
key_list = list()
|
|
57
|
-
recursion_counter=0
|
|
58
|
-
for attr,value in dictionary.items():
|
|
59
|
-
|
|
85
|
+
recursion_counter = 0
|
|
86
|
+
for attr, value in dictionary.items():
|
|
87
|
+
|
|
60
88
|
try:
|
|
61
|
-
if
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
89
|
+
if _isinstance_exclude_obj(value):
|
|
90
|
+
next(attrs)
|
|
91
|
+
elif isinstance(value, dict):
|
|
92
|
+
subkey_data = generate_dict_structure(value)
|
|
93
|
+
if len(subkey_data) > 0:
|
|
94
|
+
key_data.update({attr: subkey_data})
|
|
95
|
+
|
|
67
96
|
elif isinstance(value, (list, tuple, numbers.Number, str)):
|
|
68
97
|
key_list.append(attr)
|
|
69
|
-
|
|
98
|
+
|
|
70
99
|
elif _isinstance_pandas(value):
|
|
71
100
|
key_list.append(attr)
|
|
72
|
-
|
|
101
|
+
|
|
73
102
|
elif _isinstance_datetime(value):
|
|
74
103
|
key_list.append(attr)
|
|
75
|
-
|
|
104
|
+
|
|
76
105
|
elif _isinstance_numpy(value):
|
|
77
106
|
key_list.append(attr)
|
|
78
|
-
|
|
107
|
+
|
|
79
108
|
elif type(value) == "method":
|
|
80
109
|
if include_method:
|
|
81
110
|
key_list.append(attr)
|
|
82
111
|
else:
|
|
83
112
|
next(attr)
|
|
84
|
-
|
|
85
113
|
else:
|
|
86
|
-
|
|
87
|
-
recursion_counter = recursion_counter+1
|
|
88
|
-
|
|
114
|
+
|
|
115
|
+
recursion_counter = recursion_counter + 1
|
|
116
|
+
|
|
89
117
|
if recursion_counter > recursion_limit:
|
|
90
|
-
print(
|
|
118
|
+
print(
|
|
119
|
+
f"recursion counter exceed the limit of {recursion_limit}... return"
|
|
120
|
+
)
|
|
91
121
|
return
|
|
92
|
-
|
|
93
|
-
subkey_data = generate_object_structure(
|
|
122
|
+
|
|
123
|
+
subkey_data = generate_object_structure(
|
|
124
|
+
value,
|
|
125
|
+
recursion_counter=recursion_counter,
|
|
126
|
+
recursion_limit=recursion_limit,
|
|
127
|
+
include_method=include_method,
|
|
128
|
+
)
|
|
94
129
|
if len(subkey_data) > 0:
|
|
95
130
|
key_data.update({attr: subkey_data})
|
|
96
131
|
|
|
97
132
|
except:
|
|
98
133
|
pass
|
|
99
|
-
|
|
134
|
+
|
|
100
135
|
for attr, value in key_data.items():
|
|
101
136
|
key_list.append({attr: value})
|
|
102
|
-
|
|
137
|
+
|
|
103
138
|
return key_list
|
|
104
139
|
|
|
105
140
|
|
|
106
|
-
def
|
|
141
|
+
def generate_object_from_dictionary(dictionary):
|
|
142
|
+
|
|
143
|
+
class Object:
|
|
144
|
+
def __init__(self):
|
|
145
|
+
pass
|
|
146
|
+
|
|
147
|
+
obj = Object()
|
|
148
|
+
|
|
149
|
+
if isinstance(dictionary, dict):
|
|
150
|
+
for attr, value in dictionary.items():
|
|
151
|
+
|
|
152
|
+
if isinstance(value, (dict, list, tuple)):
|
|
153
|
+
setattr(obj, attr, generate_object_from_dictionary(value))
|
|
154
|
+
else:
|
|
155
|
+
setattr(obj, attr, value)
|
|
156
|
+
elif isinstance(dictionary, (list, tuple)):
|
|
157
|
+
return dictionary
|
|
158
|
+
# for attr in dictionary:
|
|
159
|
+
# setattr(obj, attr, None)
|
|
160
|
+
|
|
161
|
+
return obj
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def map_dict_to_object(structure, dictionary, obj):
|
|
165
|
+
"""
|
|
166
|
+
Map a dictionary to an object knowing its structure.
|
|
167
|
+
Structure must be generated with generate_dict_structure or generate_object_structure. If the object or an attribute of this object is
|
|
168
|
+
None, a empty object is created to be able to set new attribute.
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
class Object:
|
|
172
|
+
def __init__(self):
|
|
173
|
+
pass
|
|
174
|
+
|
|
175
|
+
if obj is None:
|
|
176
|
+
obj = Object()
|
|
177
|
+
|
|
178
|
+
if isinstance(structure, dict):
|
|
179
|
+
|
|
180
|
+
for attr, value in structure.items():
|
|
181
|
+
if isinstance(value, (dict, list, tuple)):
|
|
182
|
+
|
|
183
|
+
if not hasattr(obj, attr):
|
|
184
|
+
setattr(obj, str(attr), Object())
|
|
185
|
+
else:
|
|
186
|
+
if getattr(obj, attr) is None:
|
|
187
|
+
setattr(obj, str(attr), Object())
|
|
188
|
+
|
|
189
|
+
map_dict_to_object(value, dictionary[attr], getattr(obj, attr))
|
|
190
|
+
else:
|
|
191
|
+
v = None
|
|
192
|
+
if attr in dictionary.keys():
|
|
193
|
+
v = dictionary[attr]
|
|
194
|
+
|
|
195
|
+
setattr(obj, str(attr), v)
|
|
196
|
+
|
|
197
|
+
elif isinstance(structure, (list, tuple)):
|
|
198
|
+
|
|
199
|
+
for attr in structure:
|
|
200
|
+
if isinstance(attr, (dict, list, tuple)):
|
|
201
|
+
map_dict_to_object(attr, dictionary, obj)
|
|
202
|
+
else:
|
|
203
|
+
v = None
|
|
204
|
+
if attr in dictionary.keys():
|
|
205
|
+
v = dictionary[attr]
|
|
206
|
+
|
|
207
|
+
setattr(obj, str(attr), v)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def generate_object_structure(
|
|
211
|
+
instance, recursion_counter=0, recursion_limit=100, include_method=True
|
|
212
|
+
):
|
|
107
213
|
"""
|
|
108
|
-
|
|
214
|
+
|
|
109
215
|
this function create a full dictionnary containing all the structure of an object in order to save it to an hdf5
|
|
110
216
|
|
|
111
217
|
Parameters
|
|
112
218
|
----------
|
|
113
|
-
|
|
219
|
+
|
|
114
220
|
instance : object
|
|
115
221
|
a custom python object.
|
|
116
222
|
recursion_limit : int
|
|
@@ -122,33 +228,36 @@ def generate_object_structure(instance,recursion_counter=0,recursion_limit=100,i
|
|
|
122
228
|
|
|
123
229
|
Returns
|
|
124
230
|
-------
|
|
125
|
-
|
|
231
|
+
|
|
126
232
|
list or dict :
|
|
127
233
|
A list or dictionary matching the structure of the python object.
|
|
128
|
-
|
|
234
|
+
|
|
129
235
|
"""
|
|
130
236
|
key_data = {}
|
|
131
237
|
key_list = list()
|
|
132
238
|
return_list = False
|
|
133
|
-
recursion_counter
|
|
239
|
+
# recursion_counter += 1
|
|
134
240
|
for attr in dir(instance):
|
|
135
|
-
|
|
241
|
+
|
|
136
242
|
if not attr.startswith("_") and not attr in ["from_handle", "copy"]:
|
|
137
|
-
|
|
243
|
+
|
|
138
244
|
try:
|
|
139
245
|
value = getattr(instance, attr)
|
|
140
|
-
|
|
141
|
-
if
|
|
246
|
+
|
|
247
|
+
if _isinstance_exclude_obj(value):
|
|
248
|
+
next(attr)
|
|
249
|
+
|
|
250
|
+
elif isinstance(value, (list, tuple)):
|
|
142
251
|
key_list.append(attr)
|
|
143
252
|
return_list = True
|
|
144
|
-
|
|
253
|
+
|
|
145
254
|
elif _isinstance_numpy(value):
|
|
146
255
|
key_list.append(attr)
|
|
147
256
|
return_list = True
|
|
148
|
-
|
|
257
|
+
|
|
149
258
|
elif isinstance(value, dict):
|
|
150
|
-
|
|
151
|
-
depp_key_data=generate_dict_structure(value)
|
|
259
|
+
|
|
260
|
+
depp_key_data = generate_dict_structure(value)
|
|
152
261
|
if len(depp_key_data) > 0:
|
|
153
262
|
key_data.update({attr: depp_key_data})
|
|
154
263
|
|
|
@@ -166,24 +275,35 @@ def generate_object_structure(instance,recursion_counter=0,recursion_limit=100,i
|
|
|
166
275
|
return_list = True
|
|
167
276
|
else:
|
|
168
277
|
next(attr)
|
|
169
|
-
|
|
278
|
+
|
|
170
279
|
elif _isinstance_pandas(value):
|
|
171
280
|
key_list.append(attr)
|
|
172
281
|
return_list = True
|
|
173
|
-
|
|
282
|
+
|
|
174
283
|
elif _isinstance_datetime(value):
|
|
175
284
|
key_list.append(attr)
|
|
176
285
|
return_list = True
|
|
177
|
-
|
|
286
|
+
|
|
287
|
+
# ~ elif value is None:
|
|
288
|
+
# ~ key_list.append(attr)
|
|
289
|
+
# ~ return_list = True
|
|
290
|
+
|
|
178
291
|
else:
|
|
179
|
-
|
|
180
|
-
recursion_counter = recursion_counter+1
|
|
181
|
-
|
|
292
|
+
|
|
293
|
+
recursion_counter = recursion_counter + 1
|
|
294
|
+
|
|
182
295
|
if recursion_counter > recursion_limit:
|
|
183
|
-
print(
|
|
296
|
+
print(
|
|
297
|
+
f"recursion counter exceed the limit of {recursion_limit}... return"
|
|
298
|
+
)
|
|
184
299
|
return
|
|
185
|
-
|
|
186
|
-
depp_key_data = generate_object_structure(
|
|
300
|
+
|
|
301
|
+
depp_key_data = generate_object_structure(
|
|
302
|
+
value,
|
|
303
|
+
recursion_counter=recursion_counter,
|
|
304
|
+
recursion_limit=recursion_limit,
|
|
305
|
+
include_method=include_method,
|
|
306
|
+
)
|
|
187
307
|
|
|
188
308
|
if len(depp_key_data) > 0:
|
|
189
309
|
key_data.update({attr: depp_key_data})
|
|
@@ -203,14 +323,14 @@ def generate_object_structure(instance,recursion_counter=0,recursion_limit=100,i
|
|
|
203
323
|
return key_data
|
|
204
324
|
|
|
205
325
|
|
|
206
|
-
def read_object_as_dict(instance, recursion_counter=0,recursion_limit=100):
|
|
326
|
+
def read_object_as_dict(instance, recursion_counter=0, recursion_limit=100):
|
|
207
327
|
"""
|
|
208
|
-
|
|
328
|
+
|
|
209
329
|
create a dictionary from a custom python object
|
|
210
330
|
|
|
211
331
|
Parameters
|
|
212
332
|
----------
|
|
213
|
-
|
|
333
|
+
|
|
214
334
|
instance : object
|
|
215
335
|
an custom python object
|
|
216
336
|
recursion_limit : int
|
|
@@ -220,32 +340,35 @@ def read_object_as_dict(instance, recursion_counter=0,recursion_limit=100):
|
|
|
220
340
|
|
|
221
341
|
Return
|
|
222
342
|
------
|
|
223
|
-
|
|
343
|
+
|
|
224
344
|
key_data: dict
|
|
225
345
|
an dictionary containing all keys and atributes of the object
|
|
226
|
-
|
|
346
|
+
|
|
227
347
|
"""
|
|
228
348
|
key_data = {}
|
|
229
|
-
recursion_counter = 0
|
|
349
|
+
# recursion_counter = 0
|
|
230
350
|
for attr in dir(instance):
|
|
231
|
-
#print(attr)
|
|
351
|
+
# print(attr)
|
|
232
352
|
if not attr.startswith("_") and not attr in ["from_handle", "copy"]:
|
|
233
353
|
try:
|
|
234
354
|
value = getattr(instance, attr)
|
|
235
|
-
|
|
236
|
-
if
|
|
237
|
-
|
|
355
|
+
|
|
356
|
+
if _isinstance_exclude_obj(value):
|
|
357
|
+
next(attr)
|
|
358
|
+
|
|
359
|
+
elif isinstance(value, (list, tuple)):
|
|
360
|
+
|
|
238
361
|
if isinstance(value, list):
|
|
239
|
-
value = np.array(value).astype(
|
|
362
|
+
value = np.array(value).astype("U")
|
|
240
363
|
|
|
241
364
|
if value.dtype == "object" or value.dtype.char == "U":
|
|
242
365
|
value = value.astype("U")
|
|
243
|
-
|
|
366
|
+
|
|
244
367
|
key_data.update({attr: value})
|
|
245
|
-
|
|
368
|
+
|
|
246
369
|
elif isinstance(value, dict):
|
|
247
370
|
key_data.update({attr: value})
|
|
248
|
-
|
|
371
|
+
|
|
249
372
|
elif isinstance(value, numbers.Number):
|
|
250
373
|
key_data.update({attr: value})
|
|
251
374
|
|
|
@@ -254,33 +377,38 @@ def read_object_as_dict(instance, recursion_counter=0,recursion_limit=100):
|
|
|
254
377
|
|
|
255
378
|
elif type(value) == "method":
|
|
256
379
|
next(attr)
|
|
257
|
-
|
|
380
|
+
|
|
258
381
|
elif _isinstance_pandas(value):
|
|
259
382
|
if value.dtype == "object" or value.dtype.char == "U":
|
|
260
383
|
value = value.astype("U")
|
|
261
384
|
key_data.update({attr: value})
|
|
262
|
-
|
|
385
|
+
|
|
263
386
|
elif _isinstance_datetime(value):
|
|
264
387
|
if value.dtype == "object" or value.dtype.char == "U":
|
|
265
388
|
value = value.astype("U")
|
|
266
389
|
key_data.update({attr: value})
|
|
267
|
-
|
|
390
|
+
|
|
268
391
|
elif _isinstance_numpy(value):
|
|
269
392
|
if value.dtype == "object" or value.dtype.char == "U":
|
|
270
393
|
value = value.astype("U")
|
|
271
394
|
key_data.update({attr: value})
|
|
272
395
|
|
|
273
396
|
else:
|
|
274
|
-
|
|
275
|
-
recursion_counter = recursion_counter+1
|
|
276
|
-
|
|
397
|
+
|
|
398
|
+
recursion_counter = recursion_counter + 1
|
|
399
|
+
|
|
277
400
|
if recursion_counter > recursion_limit:
|
|
278
|
-
print(
|
|
401
|
+
print(
|
|
402
|
+
f"recursion counter exceed the limit of {recursion_limit}... return"
|
|
403
|
+
)
|
|
279
404
|
return
|
|
280
|
-
|
|
405
|
+
|
|
281
406
|
depp_key_data = read_object_as_dict(
|
|
282
|
-
value,
|
|
283
|
-
|
|
407
|
+
value,
|
|
408
|
+
recursion_counter=recursion_counter,
|
|
409
|
+
recursion_limit=recursion_limit,
|
|
410
|
+
)
|
|
411
|
+
|
|
284
412
|
if len(depp_key_data) > 0:
|
|
285
413
|
key_data.update({attr: depp_key_data})
|
|
286
414
|
|
|
@@ -3,6 +3,8 @@ if __name__ == "__main__":
|
|
|
3
3
|
import pyhdf5_handler
|
|
4
4
|
import datetime
|
|
5
5
|
import pandas as pd
|
|
6
|
+
import geopandas
|
|
7
|
+
import shapely
|
|
6
8
|
|
|
7
9
|
# open an hdf5 database, test.hdf5.
|
|
8
10
|
hdf5 = pyhdf5_handler.open_hdf5("./test.hdf5")
|
|
@@ -20,7 +22,9 @@ if __name__ == "__main__":
|
|
|
20
22
|
hdf5, "timestamp_numpy", np.datetime64("2019-09-22T17:38:30")
|
|
21
23
|
)
|
|
22
24
|
pyhdf5_handler.hdf5_dataset_creator(
|
|
23
|
-
hdf5,
|
|
25
|
+
hdf5,
|
|
26
|
+
"timestamp_datetime",
|
|
27
|
+
datetime.datetime.fromisoformat("2019-09-22T17:38:30"),
|
|
24
28
|
)
|
|
25
29
|
pyhdf5_handler.hdf5_dataset_creator(
|
|
26
30
|
hdf5, "timestamp_pandas", pd.Timestamp("2019-09-22T17:38:30")
|
|
@@ -31,7 +35,10 @@ if __name__ == "__main__":
|
|
|
31
35
|
pyhdf5_handler.hdf5_dataset_creator(
|
|
32
36
|
hdf5,
|
|
33
37
|
"list_date_numpy",
|
|
34
|
-
[
|
|
38
|
+
[
|
|
39
|
+
np.datetime64("2019-09-22 17:38:30"),
|
|
40
|
+
np.datetime64("2019-09-22 18:38:30"),
|
|
41
|
+
],
|
|
35
42
|
)
|
|
36
43
|
pyhdf5_handler.hdf5_dataset_creator(
|
|
37
44
|
hdf5,
|
|
@@ -44,10 +51,28 @@ if __name__ == "__main__":
|
|
|
44
51
|
pyhdf5_handler.hdf5_dataset_creator(
|
|
45
52
|
hdf5,
|
|
46
53
|
"list_date_pandas",
|
|
47
|
-
[
|
|
54
|
+
[
|
|
55
|
+
pd.Timestamp("2019-09-22 17:38:30"),
|
|
56
|
+
pd.Timestamp("2019-09-22 17:38:30"),
|
|
57
|
+
],
|
|
58
|
+
)
|
|
59
|
+
pyhdf5_handler.hdf5_dataset_creator(
|
|
60
|
+
hdf5,
|
|
61
|
+
"list_date_range_pandas",
|
|
62
|
+
pd.date_range(start="1/1/2018", end="1/08/2018"),
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
pyhdf5_handler.hdf5_dataset_creator(
|
|
66
|
+
hdf5,
|
|
67
|
+
"panda_dataframe_onecolumn",
|
|
68
|
+
pd.DataFrame({"column1": np.array([1, 2, 3])}),
|
|
48
69
|
)
|
|
49
70
|
pyhdf5_handler.hdf5_dataset_creator(
|
|
50
|
-
hdf5,
|
|
71
|
+
hdf5,
|
|
72
|
+
"panda_dataframe",
|
|
73
|
+
pd.DataFrame(
|
|
74
|
+
{"column1": np.array([1, 2, 3]), "column2": np.array([4, 5, 6])}
|
|
75
|
+
),
|
|
51
76
|
)
|
|
52
77
|
|
|
53
78
|
# write a python dictionary in the hdf5 database
|
|
@@ -86,7 +111,9 @@ if __name__ == "__main__":
|
|
|
86
111
|
data = pyhdf5_handler.read_hdf5_as_dict(hdf5, read_attrs=True)
|
|
87
112
|
|
|
88
113
|
# read a specific item
|
|
89
|
-
pyhdf5_handler.hdf5_read_dataset(
|
|
114
|
+
pyhdf5_handler.hdf5_read_dataset(
|
|
115
|
+
item=hdf5["str"], expected_type=hdf5.attrs["_str"]
|
|
116
|
+
)
|
|
90
117
|
pyhdf5_handler.hdf5_read_dataset(
|
|
91
118
|
item=hdf5["numpy_numbers"], expected_type=hdf5.attrs["_numpy_numbers"]
|
|
92
119
|
)
|
|
@@ -94,7 +121,18 @@ if __name__ == "__main__":
|
|
|
94
121
|
item=hdf5["numbers"], expected_type=hdf5.attrs["_numbers"]
|
|
95
122
|
)
|
|
96
123
|
pyhdf5_handler.hdf5_read_dataset(
|
|
97
|
-
item=hdf5["list_date_numpy"],
|
|
124
|
+
item=hdf5["list_date_numpy"],
|
|
125
|
+
expected_type=hdf5.attrs["_list_date_numpy"],
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# getting specific item
|
|
129
|
+
pyhdf5_handler.get_hdf5_item(
|
|
130
|
+
hdf5_instance=hdf5,
|
|
131
|
+
location="./panda_dataframe",
|
|
132
|
+
)
|
|
133
|
+
pyhdf5_handler.get_hdf5_item(
|
|
134
|
+
hdf5_instance=hdf5,
|
|
135
|
+
location="./structured_array",
|
|
98
136
|
)
|
|
99
137
|
|
|
100
138
|
# close the hdf5
|
|
@@ -104,10 +142,40 @@ if __name__ == "__main__":
|
|
|
104
142
|
pyhdf5_handler.hdf5file_ls("./test.hdf5")
|
|
105
143
|
pyhdf5_handler.hdf5file_ls("./test.hdf5", location="structured_array")
|
|
106
144
|
|
|
107
|
-
data = pyhdf5_handler.read_hdf5file_as_dict(
|
|
145
|
+
data = pyhdf5_handler.read_hdf5file_as_dict(
|
|
146
|
+
"./test.hdf5", read_attrs=False
|
|
147
|
+
)
|
|
108
148
|
|
|
109
149
|
pyhdf5_handler.save_dict_to_hdf5file("./test.hdf5", data)
|
|
110
150
|
|
|
151
|
+
# complex class with exluded datatype
|
|
152
|
+
pyhdf5_handler.EXCLUDE_PYTHON_OBJ.append("numpy") # exclude numpy also
|
|
153
|
+
mydict = {
|
|
154
|
+
"g": geopandas.GeoDataFrame(),
|
|
155
|
+
"s": shapely.Polygon(),
|
|
156
|
+
"n_exclude": np.zeros(0),
|
|
157
|
+
}
|
|
158
|
+
pyhdf5_handler.save_dict_to_hdf5file("./test.hdf5", mydict)
|
|
159
|
+
pyhdf5_handler.get_hdf5file_item(
|
|
160
|
+
path_to_hdf5="./test.hdf5",
|
|
161
|
+
location="./",
|
|
162
|
+
item="g",
|
|
163
|
+
search_attrs=False,
|
|
164
|
+
)
|
|
165
|
+
pyhdf5_handler.get_hdf5file_item(
|
|
166
|
+
path_to_hdf5="./test.hdf5",
|
|
167
|
+
location="./",
|
|
168
|
+
item="s",
|
|
169
|
+
search_attrs=False,
|
|
170
|
+
)
|
|
171
|
+
pyhdf5_handler.get_hdf5file_item(
|
|
172
|
+
path_to_hdf5="./test.hdf5",
|
|
173
|
+
location="./",
|
|
174
|
+
item="n_exclude",
|
|
175
|
+
search_attrs=False,
|
|
176
|
+
)
|
|
177
|
+
pyhdf5_handler.EXCLUDE_PYTHON_OBJ.remove("numpy")
|
|
178
|
+
|
|
111
179
|
res = pyhdf5_handler.search_in_hdf5file(
|
|
112
180
|
"./test.hdf5", key="date_range", location="./", wait_time=0
|
|
113
181
|
)
|
|
@@ -124,15 +192,24 @@ if __name__ == "__main__":
|
|
|
124
192
|
)
|
|
125
193
|
|
|
126
194
|
pyhdf5_handler.get_hdf5file_item(
|
|
127
|
-
path_to_hdf5="./test.hdf5",
|
|
195
|
+
path_to_hdf5="./test.hdf5",
|
|
196
|
+
location="./",
|
|
197
|
+
item="list_mixte",
|
|
198
|
+
search_attrs=False,
|
|
128
199
|
)
|
|
129
200
|
|
|
130
201
|
pyhdf5_handler.get_hdf5file_item(
|
|
131
|
-
path_to_hdf5="./test.hdf5",
|
|
202
|
+
path_to_hdf5="./test.hdf5",
|
|
203
|
+
location="./",
|
|
204
|
+
item="attribute",
|
|
205
|
+
search_attrs=True,
|
|
132
206
|
)
|
|
133
207
|
|
|
134
208
|
pyhdf5_handler.get_hdf5file_attribute(
|
|
135
|
-
path_to_hdf5="./test.hdf5",
|
|
209
|
+
path_to_hdf5="./test.hdf5",
|
|
210
|
+
location="./",
|
|
211
|
+
attribute="_list_num",
|
|
212
|
+
wait_time=0,
|
|
136
213
|
)
|
|
137
214
|
|
|
138
215
|
pyhdf5_handler.get_hdf5file_attribute(
|
pyhdf5_handler-0.6/test.hdf5
DELETED
|
Binary file
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import pyhdf5_handler
|
|
2
|
-
import numpy as np
|
|
3
|
-
|
|
4
|
-
#states
|
|
5
|
-
pyhdf5_handler.hdf5file_view("202309010300_states.hdf5")
|
|
6
|
-
|
|
7
|
-
res=pyhdf5_handler.read_hdf5file_as_dict("202309010300_states.hdf5")
|
|
8
|
-
res.keys()
|
|
9
|
-
res["202309010300"].keys()
|
|
10
|
-
res["202309010300"]["keys"][0].decode()
|
|
11
|
-
res["202309010300"]["keys"][:].astype("str")
|
|
12
|
-
|
|
13
|
-
states=res["202309010300"]["values"]
|
|
14
|
-
|
|
15
|
-
states=pyhdf5_handler.get_hdf5file_item("202309010300_states.hdf5",location="./202309010300",item="values")
|
|
16
|
-
|
|
17
|
-
search=pyhdf5_handler.search_in_hdf5file("202309010300_states.hdf5","values")
|
|
18
|
-
res=search[0]
|
|
19
|
-
res.keys()
|
|
20
|
-
res["path"]
|
|
21
|
-
res["key"]
|
|
22
|
-
res["datatype"]
|
|
23
|
-
res["value"]
|
|
24
|
-
|
|
25
|
-
#prévis ensemble:
|
|
26
|
-
pyhdf5_handler.hdf5file_view("20230901030000_qens.hdf5")
|
|
27
|
-
|
|
28
|
-
res=pyhdf5_handler.read_hdf5file_as_dict("20230901030000_qens.hdf5")
|
|
29
|
-
|
|
30
|
-
res.keys()
|
|
31
|
-
res["20230901030000"].keys()
|
|
32
|
-
Q=res["20230901030000"]["member0"]
|
|
33
|
-
|
|
34
|
-
Q=pyhdf5_handler.get_hdf5file_item("20230901030000_qens.hdf5",location="./20230901030000",item="member8")
|
|
35
|
-
|
|
36
|
-
search=pyhdf5_handler.search_in_hdf5file("20230901030000_qens.hdf5","member8")
|
|
37
|
-
res=search[0]
|
|
38
|
-
res.keys()
|
|
39
|
-
res["path"]
|
|
40
|
-
res["key"]
|
|
41
|
-
res["datatype"]
|
|
42
|
-
res["value"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/.spyproject/config/defaults/defaults-codestyle-0.2.0.ini
RENAMED
|
File without changes
|
{pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/.spyproject/config/defaults/defaults-encoding-0.2.0.ini
RENAMED
|
File without changes
|
{pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/.spyproject/config/defaults/defaults-vcs-0.2.0.ini
RENAMED
|
File without changes
|
{pyhdf5_handler-0.6 → pyhdf5_handler-0.8}/.spyproject/config/defaults/defaults-workspace-0.2.0.ini
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|