Frage Verketten Sie eine große Anzahl von HDF5-Dateien


Ich habe ungefähr 500 HDF5-Dateien von jeweils etwa 1,5 GB.

Jede der Dateien hat dieselbe exakte Struktur, nämlich 7 zusammengesetzte (int, double, double) Datensätze und eine variable Anzahl von Samples.

Jetzt möchte ich all diese Dateien verketten, indem ich jeden der Datensätze so verkette, dass ich am Ende eine einzige 750-GB-Datei mit meinen 7 Datensätzen habe.

Momentan benutze ich ein h5py Skript, welches:

  • erstellt eine HDF5-Datei mit den richtigen Datensätzen von unbegrenzt max
  • Öffnen Sie nacheinander alle Dateien
  • Überprüfen Sie, wie viele Samples es gibt (da es variabel ist)
  • Ändern Sie die Größe der globalen Datei
  • füge die Daten an

das dauert natürlich viele Stunden, Hättest du einen Vorschlag zur Verbesserung?

Ich arbeite an einem Cluster, also könnte ich HDF5 parallel verwenden, aber ich bin nicht gut genug darin C Programmierung, um selbst etwas zu implementieren, würde ich ein Tool bereits geschrieben haben.


9
2018-03-17 23:39


Ursprung


Antworten:


Ich fand heraus, dass die meiste Zeit damit verbracht wurde, die Größe der Datei zu ändern, da ich bei jedem Schritt die Größe änderte, also gehe ich jetzt zuerst alle meine Dateien durch und erhalte ihre Länge (sie ist variabel).

Dann erstelle ich die globale h5-Datei, die die Gesamtlänge auf die Summe aller Dateien setzt.

Erst nach dieser Phase fülle ich die h5-Datei mit den Daten aus allen kleinen Dateien.

Jetzt dauert es ungefähr 10 Sekunden für jede Datei, also sollte es weniger als 2 Stunden dauern, während vorher viel mehr benötigt wurde.


9
2018-03-21 18:08



Ich bekomme durch die Beantwortung davon ein Nekro-Abzeichen - aber in letzter Zeit haben sich die Dinge für mich verbessert.

In Julia dauert das ein paar Sekunden.

  1. Erstelle eine txt-Datei, die alle hdf5-Dateipfade auflistet (du kannst bash dafür verwenden, wenn es viele gibt)
  2. In einer Schleife lesen Sie jede Zeile der TXT-Datei und verwenden Sie sie label$i = h5read(original_filepath$i, "/label")
  3. concat alle Etiketten Label = [Label Label $ i]
  4. Dann schreibe einfach: h5write(data_file_path, "/label", label)

Das Gleiche kann gemacht werden, wenn Sie Gruppen oder kompliziertere HDF5-Dateien haben.


1
2018-02-11 07:34



Ashleys Antwort funktionierte gut für mich. Hier ist eine Implementierung ihres Vorschlags in Julia:

Erstellen Sie eine Textdatei, die die Dateien auflistet, die in Bash verkettet werden sollen:

ls -rt $somedirectory/$somerootfilename-*.hdf5 >> listofHDF5files.txt

Schreiben Sie ein julia-Skript, um mehrere Dateien in einer Datei zu verketten:

# concatenate_HDF5.jl
using HDF5

inputfilepath=ARGS[1]
outputfilepath=ARGS[2]

f = open(inputfilepath)
firstit=true
data=[]
for line in eachline(f)
    r = strip(line, ['\n'])
    print(r,"\n")
    datai = h5read(r, "/data")
    if (firstit)
        data=datai
        firstit=false
    else
        data=cat(4,data, datai) #In this case concatenating on 4th dimension
    end
end
h5write(outputfilepath, "/data", data)

Führen Sie dann die obige Skriptdatei aus mit:

julia concatenate_HDF5.jl listofHDF5files.txt final_concatenated_HDF5.hdf5

1
2017-08-17 17:14