2015-05-06 19 views
14

sto sperimentando alcune interazioni davvero strano tra h5py, PyTables (via Pandas), e C++ generati HDF5 file. Sembra che, h5check e h5py sembrano gestire i nomi di tipo contenenti '/', ma non lo è pandas/PyTables. Chiaramente, c'è una lacuna nella mia comprensione, quindi:'/' nei nomi di file HDF5 confusione

Cosa non ho capito qui?


I dettagli scabrosi

ho i seguenti dati in un file di HDF5:

[...] 
    DATASET "log" { 
     DATATYPE H5T_COMPOUND { 
     H5T_COMPOUND { 
      H5T_STD_U32LE "sec"; 
      H5T_STD_U32LE "usec"; 
     } "time"; 
     H5T_IEEE_F32LE "CIF/align/aft_port_end/extend_pressure"; 
     [...] 

questo è stato creato tramite l'API C++. L'utility h5check dice che il file è valido.

Si noti che CIF/align/aft_port_end/extend_pressurenon è inteso come percorso per un gruppo/nodo/foglia. È un'etichetta, che usiamo internamente, che ha una struttura interna che contiene '/' come delimitatori. Non vogliamo che il file HDF5 sappia nulla a riguardo: non dovrebbe importare. Chiaramente, se '/' sono illegali in qualsiasi nome HDF5, allora dobbiamo cambiare quel delimitatore in qualcos'altro.

Utilizzando PyTables (ok, Pandas ma utilizza PyTables internamente) per leggere il file, ottengo un

>>> import pandas as pd 
>>> store = pd.HDFStore('data/XXX-20150423-071618.h5') 
>>> store 
/home/XXX/virt/env/develop/lib/python2.7/site-packages/tables/group. py:1156: UserWarning: problems loading leaf ``/log``:: 

    the ``/`` character is not allowed in object names: 'XXX/align/aft_port_end/extend_pressure' 

The leaf will become an ``UnImplemented`` node. 

ho chiesto spiegazioni in questo question e got told che '/' sono illegal in the specification. Tuttavia, le cose si fanno sconosciuto con h5py ...

Utilizzando h5py per leggere il file, ottengo ciò che voglio:

>>> f['/log'].dtype 
>>> dtype([('time', [('sec', '<u4'), ('usec', '<u4')]), ('CI 
F/align/aft_port_end/extend_pressure', '<f4')[...] 

che è più o meno quello che ho deciso con.

Inutile dire che sono confuso. Sono riuscito a creare un file HDF5 illegale che in qualche modo supera h5check? PyTables non supporta questo caso limite? ... Sono confuso.


Chiaramente, potrei scrivere un semplice involucro qualcosa di simile:

>>> import matplotlib.pyplot as plt 
>>> silly = pd.DataFrame(f['/log']['CIF/align/aft_port_end/extend_pressure']) 
>>> silly.plot() 
>>> plt.show() 

per ottenere tutti i dati dal file HDF5 in Pandas. Tuttavia, non sono sicuro che questa sia una buona idea a causa della confusione precedente. La mia più grande preoccupazione è la conversione potrebbe non scalare se i dati sono molto grandi ...

risposta

5

Ho sfogliato un po 'il h5check source e non riesco a trovare alcun posto dove si verifica se un nome contiene una barra. È possibile esaminare i messaggi di errore che può produrre con:

grep error_push h5checker.c -A1 

Il link che hai fornito chiaramente che le barre non sono consentiti in nomi degli oggetti. Quindi sì, penso che tu abbia fatto un file che è illegale ma passa h5check. Lo strumento sembra concentrarsi maggiormente sul layout dei dati binari. Il controllo relativo più vicino che riesco a trovare è una guardia contro i nomi duplicati.

Secondo me è tutto lì. Il fatto che h5py e altre librerie siano in qualche modo in grado di creare o leggere questo file illegale è irrilevante. La specifica dice "non inserire barre nei nomi degli oggetti", quindi non lo fai. Fine della storia.

Se non sei convinto, pensa in questo modo: se in qualche modo sei riuscito a creare un file regolare con una barra nel nome del file, cosa accadrebbe? La maggior parte dei programmi presuppone che i nomi dei file non contengano barre e quindi siano in grado di partizionare un percorso di directory suddividendolo nei caratteri della barra. Il tuo file interromperà questo comportamento e introdurrà molti bug sottili (e non così sottili). Gli utenti si lamenterebbero, i programmatori ti odieranno, gli amministratori di sistema ti malediranno.

Allo stesso modo è lecito supporre che, accanto a PyTables, molte altre librerie e programmi non saranno in grado di gestire le barre nei nomi di variabili. La cosa bella dell'HDF è che esistono così tanti strumenti e, usando le barre, questo vantaggio viene eliminato. Potresti pensare che questo non sia importante, forse i tuoi file HDF-5 sono solo per uso interno. Tuttavia, la situazione può cambiare in 5 anni, come le situazioni tendono a fare.

Basta mordere il proiettile e sostituire "/" con "|" prima di scrivere le tue variabili su HDF5. Sostituiscili quando li leggi. Il tempo che si perde implementando questo, si vincerà di nuovo x-fold (per x> 1) evitando futuri bug e reclami degli utenti.

Scusate per il rant ma spero di averti convinto.

+0

In alto votati, accettati e generosi come questa è stata la migliore risposta. – Sardathrion

+1

@Sardathrion, il tuo file è perfettamente a posto. Non sono presenti restrizioni relative alle barre di cui sono a conoscenza sulle etichette dei membri del tipo composto. Il documento che hai collegato fa riferimento ai nomi nello spazio dei nomi "gruppo"; cioè i percorsi in stile POSIX agli oggetti nel file. –

+0

@ andrew-collette: pensi che sia un bug in PyTables allora? Sardathrion, anche se ho apparentemente interpretato erroneamente le specifiche e il file è corretto, sostengo il mio punto: utilizzando le barre si rischia di imbattersi in problemi con altre librerie e programmi. Questo può essere facilmente evitato sostituendoli. – titusjan

2

Si può usare h5py per leggere tutti i file e riscriverli senza i caratteri offensivi, in modo che pytables li possa leggere?

Se è al di fuori delle specifiche, suppongo quello che stai vivendo è solo che alcune implementazioni di gestirlo e altri no ...

+0

Questa sarebbe una correzione una tantum fintanto che è possibile aggiornare l'API C++ da cui provengono i caratteri non validi. O dovrai mettere questo passaggio di pre-elaborazione nel tuo flusso di lavoro. – tmthydvnprt

+0

La prima parte riguarda la mia ultima modifica: sì, posso farlo. Tuttavia, sembra un po 'forzato. L'ultima parte, non sono sicuro se è al di fuori delle specifiche o no. Tutti di h5check, l'API C++ e h5py sembrano pensare che vada bene.Solo PyTables si lamenta. – Sardathrion

0

assicurarsi che si sta creando gruppi e non solo il nome del percorso fuori proprio - questo è probabilmente il punto in cui si insinua l'errore. Se crei i gruppi sui tuoi oggetti e poi dai nomi agli oggetti con i nomi delle foglie (extend_pressure in sopra) non avrai alcun problema da nessuna parte.

H5py è un involucro piuttosto sottile attorno alla libreria C HDF5, i panda/i pytables hanno un approccio molto più pesante - o almeno hanno un sacco di più della loro semantica in corso - e quindi controllano per assicurarsi non hai '/' nei nomi degli oggetti. Ma tieni a mente che tutti usano la libreria HDF5 alla fine della giornata, perché mentre HDF5 è grandioso, sarebbe un enorme sforzo per realizzare un'implementazione alternativa, al di là delle risorse di Pandas/Pytables.

Disclaimer di minore entità: ho già eseguito l'hackering su interni di HDF5 e H5py.

+0

'' CIF/align/aft_port_end/extend_pressure "' non è un percorso per un nodo/foglia di gruppo. È un nome dentro e fuori di sé, solo un'etichetta con una struttura interna a cui HDF5 non dovrebbe importare. Almeno, questa è la teoria. – Sardathrion

+0

@Sardathrion sì, era quello che ho raccolto. Pensatelo come se fosse un filesystem - un nome di file non può avere le barre del percorso (o le sue cattive pratiche almeno). Ad ogni modo mentre la libreria HDF5 funziona con esso - non vede il 100% delle specifiche anche se lo stesso gruppo ha fatto le specifiche - questa è solo una realtà. È sfortunato che creare un set di dati del genere non crei automaticamente il percorso anche per comodità, ma tale è la libreria - al fine di evitare che l'errore/problema usi correttamente i gruppi. –