J'ai un dictionnaire, où la clé est un objet datetime et la valeur est un tuple d'entiers:
>>> d.items()[0]
(datetime.datetime(2012, 4, 5, 23, 30), (14, 1014, 6, 3, 0))
Je veux le stocker dans le jeu de données HDF5, mais si j'essaye simplement de vider le dictionnaire, h5py soulève une erreur:
TypeError: Object dtype dtype ('object') n'a pas d'équivalent HDF5 natif
Quelle serait "la meilleure" façon de transformer ce dictionnaire afin que je puisse le stocker dans le jeu de données HDF5?
Plus précisément, je ne veux pas simplement vider le dictionnaire dans un tableau numpy, car cela compliquerait la récupération des données basée sur une requête datetime.
J'ai trouvé deux façons:
I) transformer l'objet datetime en chaîne et l'utiliser comme nom de jeu de données
h = h5py.File('myfile.hdf5')
for k, v in d.items():
h.create_dataset(k.strftime('%Y-%m-%dT%H:%M:%SZ'), data=np.array(v, dtype=np.int8))
où les données sont accessibles en interrogeant les chaînes de clés (nom des ensembles de données). Par exemple:
for ds in h.keys():
if '2012-04' in ds:
print(h[ds].value)
II) transformer un objet datetime en sous-groupes de jeux de données
h = h5py.File('myfile.hdf5')
for k, v in d.items():
h.create_dataset(k.strftime('%Y/%m/%d/%H:%M'), data=np.array(v, dtype=np.int8))
remarquez des barres obliques dans la chaîne strftime, ce qui créera des sous-groupes appropriés dans le fichier HDF. Les données sont accessibles directement comme h['2012']['04']['05']['23:30'].value
, Ou en itérant avec les itérateurs h5py fournis, ou même en utilisant des fonctions personnalisées via visititems()
Pour plus de simplicité, je choisis la première option.
Cette question se rapporte à la question plus générale de pouvoir stocker tout type de dictionnaire dans HDF5
format. Tout d'abord, convertissez le dictionnaire en chaîne. Ensuite, pour récupérer le dictionnaire, utilisez la bibliothèque ast
en utilisant le import ast
commande. Le code suivant donne un exemple.
>>> d = {1:"a",2:"b"}
>>> s = str(d)
>>> s
"{1: 'a', 2: 'b'}"
>>> ast.literal_eval(s)
{1: 'a', 2: 'b'}
>>> type(ast.literal_eval(s))
<type 'dict'>
De nos jours, nous avons deepdish (www.deepdish.io):
import deepdish as dd
dd.io.save(filename, {'dict1': dict1, 'dict2': dict2}, compression=('blosc', 9))
Je sérialiserais l'objet en JSON ou YAML et stockerais la chaîne résultante comme attribut dans l'objet approprié (groupe HDF5 ou jeu de données).
Je ne sais pas pourquoi vous utilisez le datetime comme nom de jeu de données, sauf si vous devez absolument rechercher votre jeu de données directement par datetime.
p.s. Pour ce que ça vaut, PyTables est beaucoup plus facile à utiliser que le h5py de bas nivea .