Ich möchte in Python einige ASCII-Dateien importieren (aus tecplot, Software für cfd-Nachbearbeitung). Regeln für diese Dateien sind (zumindest für diejenigen, die ich importieren muss):
Jeder Abschnitt hat zwei Zeilen als Header wie:
%Vor%Hier ist ein Beispiel für Daten:
%Vor% Ich bin ziemlich neu in Python und ich habe einen Code geschrieben, um die Daten in ein Wörterbuch zu importieren, indem ich die Variablen als 3D numpy.array
schreibe. Diese Dateien könnten sehr groß sein (bis zu Gb). Wie kann ich diesen Code schneller machen? (oder allgemeiner: Wie kann ich solche Dateien so schnell wie möglich importieren)?
Ps. In Python, kein Cython oder andere Sprachen
Die Umwandlung einer großen Menge von Strings in Zahlen ist immer ein wenig langsam, aber unter der Annahme, dass die dreifach verschachtelte for-Schleife der Flaschenhals ist, gibt es eine ausreichende Beschleunigung:
%Vor%Leider habe ich im Moment nur Zugriff auf mein Smartphone (kein PC), also kann ich nicht testen, wie schnell das ist oder ob es überhaupt richtig oder überhaupt funktioniert!
Aktualisieren
Endlich habe ich einige Tests gemacht:
ndarray.itemset
und wahrscheinlich auf Overhead- und Float-Konvertierung. Leider zeigt cProfile dies nicht im Detail. numpy.fromstring
, was meines Erachtens darauf hindeutet, dass diese Methode ziemlich schnell ist für das, was Sie mit Python / NumPy erreichen können. Update 2
Natürlich wäre es noch besser, die Datei zu durchlaufen, anstatt alles auf einmal zu laden. In diesem Fall ist dies etwas schneller (ich habe es ausprobiert) und reduziert die Speicherauslastung erheblich. Sie könnten auch versuchen, mehrere CPU-Kerne zu verwenden, um das Laden und die Konvertierung in Gleitkommazahlen durchzuführen, aber dann wird es schwierig, alle Daten unter einer Variablen zu haben. Abschließend ein Wort der Warnung: Die Methode fromstring
, die ich verwendet habe, skaliert ziemlich schlecht mit der Länge der Zeichenfolge. Z.B. ab einer bestimmten Stringlänge wird es effizienter, etwas wie np.fromiter(itertools.imap(float, str_vector.split()), dtype=float)
zu verwenden.
Wenn Sie hier reguläre Ausdrücke verwenden, gibt es zwei Dinge, die ich ändern würde:
Kompiliere REs, die häufiger verwendet werden (was für alle REs in deinem Beispiel gilt, denke ich). Setzen Sie regex=re.compile("<pattern>")
auf ihnen und verwenden Sie das resultierende Objekt mit match=regex.match()
, wie in die Python-Dokumentation .
Berücksichtigen Sie für die I, J, K REs, zwei REs auf eins zu reduzieren, indem Sie das Gruppierungsmerkmal (oben beschrieben) verwenden, indem Sie nach einem Muster der Form "I = (\ d +)" suchen Ergreifen Sie den Teil, der innerhalb der Klammern mit regex.group(1)
übereinstimmt. Wenn Sie dies weiterführen, können Sie eine einzelne Regex definieren, um alle drei Variablen in einem Schritt zu erfassen.
Zumindest zum Starten der Abschnitte scheinen REs etwas übertrieben zu sein: Es gibt keine Variation in der Zeichenfolge, nach der Sie suchen müssen, und string.find()
ist in diesem Fall ausreichend und wahrscheinlich schneller.
EDIT: Ich habe gerade gesehen, dass Sie die Gruppierung bereits für die Variablen verwenden ...
Tags und Links python python-2.7 numpy