Schnellster Weg, um 50k Excel-Zeilen in OpenPYXL zu durchlaufen

8

Ich benutze openpyxl in Python, und ich versuche, 50k Zeilen zu durchlaufen und Daten aus jeder Zeile zu nehmen und es in eine Datei zu legen. Aber was ich finde ist, dass es unglaublich langsam läuft, je weiter ich darauf zugreife. Die ersten 1k-Zeilen gehen superschnell, weniger als eine Minute, aber danach dauert es immer länger und länger, um die nächsten 1k Zeilen zu machen.

Ich habe eine .xlsx-Datei geöffnet. Ich frage mich, ob es schneller ist, eine .txt-Datei als CSV oder etwas zu öffnen oder eine JSON-Datei oder etwas zu lesen? Oder irgendwie zu etwas konvertieren, das schneller liest?

Ich habe 20 eindeutige Werte in einer bestimmten Spalte, und dann sind die Werte für jeden Wert zufällig. Ich versuche, einen String der gesamten eindeutigen Wertespalte für jeden Wert zu erfassen.

Wert1: 1243,345,34,124, Wert2: 1243,345,34,124, usw., usw.

Ich durchlaufe die Werteliste, um zu sehen, ob der Name in einer Datei existiert, wenn dies der Fall ist, greift er auf diese Datei zu und fügt ihr den neuen Wert hinzu, wenn die Datei nicht existiert, wird sie erstellt die Datei und dann zum Anhängen festlegen. Ich habe ein Wörterbuch, in das alle "append write file" -Dinge eingebunden sind. Wenn ich also etwas schreiben möchte, wird es den Dateinamen aufnehmen, und die Append-Datei wird im dict verfügbar sein, sie wird nachschlagen und Schreiben Sie in diese Datei, damit sie nicht jedes Mal neue Dateien öffnet, wenn sie ausgeführt wird.

Die erste 1k hat weniger als eine Minute gedauert ... jetzt bin ich auf 4k bis 5k Platten, und es läuft alle 5 Minuten .. es scheint länger zu dauern, da es in Rekorde geht, ich frage mich, wie man es beschleunigen kann oben. Es wird überhaupt nicht auf die Konsole gedruckt.

%Vor%

Ich habe dem obigen Code einige Zeitstempel hinzugefügt, er ist nicht da, aber Sie können die Ausgabe unten sehen. Das Problem, das ich sehe, ist, dass es jeden 1k-Lauf höher und höher geht. 2 Minuten die erste Zeit, dann 3 Minuten, dann 5 Minuten, dann 7 Minuten. Zu der Zeit, wenn es 50k trifft, mache ich mir Sorgen, dass es eine Stunde oder so dauern wird und es wird zu lange dauern.

%Vor%

Etwas, das ich klarstellen sollte ... Ich kenne die Namen der Werte nicht im Voraus, vielleicht sollte ich sie durchgehen und sie in einem separaten Python-Skript finden, um das schneller zu machen?

Zweitens brauche ich eine Zeichenfolge mit allen Werten, die durch ein Komma getrennt sind, deshalb lege ich sie in eine Textdatei, um sie später zu greifen. Ich dachte daran, es auf einer Liste zu machen, wie mir vorgeschlagen wurde, aber ich frage mich, ob das das gleiche Problem haben wird. Ich denke, das Problem hat mit Excel zu lesen. Wie auch immer, ich kann einen String mit Komma trennen, ich kann es anders machen.

Oder könnte ich versuchen / fangen, anstatt immer nach der Datei zu suchen, und wenn es einen Fehler gibt, kann ich davon ausgehen, eine neue Datei zu erstellen? Vielleicht macht es das Nachschlagen jedes Mal wirklich langsam? die Wenn die Datei existiert?

diese Frage ist eine Fortsetzung von meinem ursprünglichen hier und ich nahm einige Vorschläge von dort .... Was ist das schnellste Leistungstupel für große Datensätze in Python?

    
king 25.02.2016, 20:53
quelle

3 Antworten

3

Ich denke, was Sie versuchen, ist, einen Schlüssel aus Spalte B der Zeile zu holen und diesen für den Dateinamen zu verwenden, an den er angehängt werden soll. Lass es uns viel schneller machen:

%Vor%     
Austin Hastings 28.02.2016 05:48
quelle
2

Es sieht so aus, als ob Sie nur Zellen aus der B-Spalte wollen. In diesem Fall können Sie ws.get_squared_range() verwenden, um die Anzahl der zu betrachtenden Zellen einzuschränken.

%Vor%

Es ist nicht klar, was mit dem else Zweig Ihres Codes passiert, aber Sie sollten alle geöffneten Dateien schließen, sobald Sie damit fertig sind.

    
Charlie Clark 26.02.2016 09:13
quelle
2

Basierend auf der anderen Frage, auf die Sie verwiesen haben, und dem obigen Code scheint es, dass Sie eine Tabelle mit Name / Wert-Paaren haben. Der Name in Spalte A und der Wert in Spalte B. Ein Name kann mehrmals in Spalte A vorkommen, und jedes Mal kann ein anderer Wert in Spalte B angegeben werden. Das Ziel besteht darin, eine Liste aller Werte zu erstellen, die für jeden Namen angezeigt werden.

Zuerst ein paar Beobachtungen zum obigen Code:

  1. counter wird niemals initialisiert. Vermutlich wird es auf 1 initialisiert.

  2. open(textfilename,...) wird zweimal aufgerufen, ohne die Datei dazwischen zu schließen. Beim Aufrufen von open wird Speicherplatz zugewiesen, um Daten zu speichern, die sich auf die Verarbeitung der Datei beziehen. Der für den ersten offenen Aufruf zugewiesene Speicher wird möglicherweise erst viel später freigegeben, möglicherweise erst, wenn das Programm beendet ist. Es empfiehlt sich, Dateien zu schließen, wenn Sie fertig sind (siehe Öffnen als Kontextmanager).

  3. Die Schleifenlogik ist nicht korrekt. Bedenken Sie:

Erste Iteration der inneren Schleife:

%Vor%

Aber jede Zeile hat mindestens zwei Zellen, also bei der zweiten Iteration der inneren Schleife:

%Vor%

Wiederholen Sie dies für jede der 50K Zeilen. Abhängig davon, wie viele eindeutige Werte in Spalte B enthalten sind, könnte das Programm versuchen, Hunderte oder Tausende von geöffneten Dateien zu haben (basierend auf dem Inhalt der Zellen A1, B1, A2, B2, ...) == & gt; & gt; sehr langsam oder Programmabstürze.

  1. iter_rows() gibt ein Tupel der Zellen in der Zeile zurück.

  2. Wie in der anderen Frage vorgeschlagen, verwenden Sie ein Wörterbuch und Listen, um die Werte zu speichern und sie am Ende zu schreiben. Wie so (Ich benutze Python 3.5, also müssen Sie dies möglicherweise anpassen, wenn Sie 2.7 verwenden)

Hier ist eine einfache Lösung:

%Vor%     
RootTwo 03.03.2016 06:05
quelle

Tags und Links