2017-08-10 7 views
0

Ziel ist es, große Datensätze zu Tensorflow zu füttern. Ich kam zur folgenden Implementierung. Während io von HDF5 jedoch sehr schnell sein soll, ist meine Implementierung langsam. Liegt das daran, dass die Chunks-Funktion nicht verwendet wird? Ich finde die Dimensionen nicht richtig für die Brocken, sollte ich das als dritte Dimension sehen. Mögen; (4096, 7, 1000) für Chunksize 1000?Stapel lesen und schreiben, von Textdatei zu HDF5 in Python

Bitte beachten Sie, dass ich meinen Code unten vereinfacht haben könnte, indem ich eine Lösung für einen einzelnen Generator gefunden habe. Ich denke jedoch, dass die Daten/Label-Kombination sehr häufig und nützlich für andere ist.

Ich verwende die folgende Funktion, um zwei Generatoren zu erstellen, einen für die Daten und einen für die entsprechenden Beschriftungen.

Dann möchte ich die Daten und Etiketten von diesen Generatoren zu HDF5 bewegen.

def write_h5(data_gen, label_gen, out_file, batch_size, h5_batch_size, data_dtype, label_dtype): 
    # remove existing file 
    if os.path.isfile(out_file): 
     os.remove(out_file) 
    with h5py.File(out_file, 'a') as f: 
     # create a dataset and labelset in the same file 
     d = f.create_dataset('data', (batch_size,data_dim), maxshape=(None,data_dim), dtype=data_dtype) 
     l = f.create_dataset('label', (batch_size,label_dim), maxshape=(None,label_dim), dtype=label_dtype) 
     # use generators to fill both sets 
     for data in data_gen: 
      d.resize(d.shape[0]+batch_size, axis=0) 
      d[-batch_size:] = data 
      l.resize(l.shape[0]+batch_size, axis=0) 
      l[-batch_size:] = next(label_gen) 

Mit den folgenden Konstanten habe ich beide Funktionen so kombiniert;

batch_size = 4096 
h5_batch_size = 1000 
data_dim = 7 #[NUM_POINT, 9] 
label_dim = 1 #[NUM_POINT] 
data_dtype = 'float32' 
label_dtype = 'uint8' 

for data_file, label_file in data_label_files: 
    print(data_file) 
    with open(data_file, 'r') as data_f, open(label_file, 'r') as label_f: 
     data_gen = read_chunks(data_f, dim=data_dim) 
     label_gen = read_chunks(label_f, dim=label_dim) 
     out_file = data_file[:-4] + '.h5' 
     write_h5(data_gen, label_gen, out_file, batch_size, h5_batch_size, data_dtype, label_dtype) 

Antwort

3

Das Problem ist nicht, dass HDF5 langsam ist. Das Problem ist, dass Sie eine einzelne Zeile zu einer Zeit mit einer Python-Schleife lesen, genfromtxt() einmal pro Zeile aufrufen! Diese Funktion soll ganze Dateien lesen. Und dann verwenden Sie die anti-Muster von „array = vstack (array, Newstuff)` in der gleichen Schleife

Kurz gesagt, Ihr Leistungsproblem beginnt hier:.

chunk = np.vstack((chunk, np.genfromtxt(io.BytesIO(line.encode())))) 

Sie sollten nur die gesamte lesen Wenn Sie das nicht können, lesen Sie die Hälfte davon (Sie können eine maximale Anzahl von Zeilen für jedes Mal einstellen, zB 1 Million)

+0

Ich habe versucht, Chunks zu lesen, jedoch würde dies eine spezifizierte lesen Anzahl der Bytes, die mich mit halben Zeilen belassen, für die 'np.genfromtxt()' den Fehler einer anderen Anzahl von Spalten auslöst Haben Sie einen Vorschlag zum Lesen von n Zeilen? Eine andere Lösung wäre, Chunk eine einfache Liste zu machen und 'np.genfromtxt() 'auf diese Liste anzuwenden, bin ich richtig? Dies führt jedoch zu Problemen mit den 'ìo.BytesIO()' und '.encode()'. Haben Sie einen Vorschlag, wie Sie beides umsetzen können? –

+1

Im Moment habe ich das Problem gelöst, indem ich Zeilen in eine Liste geschrieben habe (Chunk genannt) und auf dieser Liste 'np.genfromtxt()' ausgeführt habe. Das Problem mit der Byte-Codierung wurde gelöst, indem die Datei im "rb" -Modus gelesen wurde. –

Verwandte Themen