2016-08-12 7 views
0

Für ein tief learning Modell muss ich meine Daten durch Reihen laden. Für jede Epoche (vollständige Iteration über alle Daten) muss jede Zeile einmal übergeben werden, aber es ist wichtig, dass die Daten dem Algorithmus in zufälliger Reihenfolge zugeführt werden. Mein Datensatz ist zu groß, um ihn vollständig im Speicher zu lesen. Es sind Sequenzdaten mit variabler Länge, das Eingabeformat kann geändert werden, da es sich um einen Dump von einem Cluster handelt, den mein anderes Skript ausgibt. Momentan sind es einige Meta-Informationen pro Zeile und dann werden die Sequenzen durch ';' geteilt.Gelesene zufällige Stücke von der Textakte

Meine aktuelle Lösung ist ein Generator, der alle Zeilennummern mischt, sie in 4 Teile zerlegt und die Datei liest, wobei die Zeilen analysiert werden, die den Chunk-Zeilennummern entsprechen. Es ergibt Sequenzen in Stapelgröße, bis nichts mehr übrig ist, und analysiert dann den nächsten Teil der Zeilennummern. Es funktioniert, aber ich denke, es könnte eine bessere Lösung geben. Wer hat einen besseren Workflow? Dies ist ein Problem, auf das ich regelmäßig stoße. Das Problem ist, dass ich die Datei für jeden Chunk, jede Epoche vollständig scanne. Obwohl ich es mit nur 4 Stücken arbeiten kann, mit 30 Epochen, die 120 mal eine große Datei lesen.

+2

* "Es ist wichtig, dass die Daten in einem zufälligen zugeführt wird Reihenfolge zum Algorithmus "* Sequential Disk I/O APIs wurden nicht für diese Art von verrückt entwickelt. - Signed, jemand, der nichts über "Deep Learning" weiß –

+0

Ich würde einen Satz der Datei mit 'set (file_obj)' machen. Verwenden Sie dann 'random.sample', um die richtige Anzahl an zufälligen Elementen zu erhalten. – zondo

+0

@zondo lädt nicht den gesamten Dateiinhalt in den Speicher? –

Antwort

3

Erstellen Sie einen Index der Zeilen im Speicher (die einen einzelnen Durchlauf durch die Datei erfordert, aber nicht alle im Speicher) und dann können Sie Zeilen zufällig und schnell zugreifen.

Diese nicht robust ist (keine Validierung/Bereichsprüfung, etc.), aber:

import sys 

BUFFER_LEN = 1024 


def findNewLines(s): 
    retval = [] 
    lastPos = 0 
    while True: 
     pos = s.find("\n", lastPos) 
     if pos >= 0: 
     pos += 1 
     retval.append(pos) 
     lastPos = pos 
     else: 
     break 
    return retval 


class RandomAccessFile(object): 
    def __init__(self, fileName): 
     self.fileName = fileName 
     self.startPositions = [0] 
     with open(fileName, "rb") as f: 
     looking = True 
     fileOffset = 0 
     while (looking): 
      bytes = f.read(BUFFER_LEN) 
      if len(bytes) < BUFFER_LEN: 
       looking = False 
      newLines = findNewLines(bytes) 
      for newLine in newLines: 
       self.startPositions.append(fileOffset+newLine) 
      fileOffset += len(bytes) 

    def GetLine(self, index): 
     start, stop = self.startPositions[index],self.startPositions[index+1]-1 
     with open(self.fileName, "rb") as f: 
     f.seek(start) 
     return f.read((stop-start)-1) 



raf = RandomAccessFile('/usr/share/dict/words') 


print raf.GetLine(0) 
print raf.GetLine(10) 
print raf.GetLine(456) 
print raf.GetLine(71015) 

Ausgabe lautet:

python indexedFile.py 
A 
Aaronic 
abrim 
flippantness 
Verwandte Themen