Ich verwende den folgenden Code:Numpy verketten ist langsam: jeder alternative Ansatz?
for i in range(1000)
My_Array=numpy.concatenate((My_Array,New_Rows[i]), axis=0)
Der obige Code langsam ist. Gibt es einen schnelleren Ansatz?
Ich verwende den folgenden Code:Numpy verketten ist langsam: jeder alternative Ansatz?
for i in range(1000)
My_Array=numpy.concatenate((My_Array,New_Rows[i]), axis=0)
Der obige Code langsam ist. Gibt es einen schnelleren Ansatz?
Dies ist im Grunde, was in allen auf Arrays basierenden Algorithmen passiert.
Jedes Mal, wenn Sie die Größe des Arrays ändern, muss es in der Größe geändert werden und jedes Element muss kopiert werden. Dies geschieht auch hier. (Einige Implementierungen reservieren einige leere Schlitze; zum Beispiel verdoppeln sie den Raum des internen Speichers mit jedem Wachsen).
Dies ist nicht viel von einem numpy-spezifischen Thema, aber viel mehr über Datenstrukturen.
Bearbeiten: als diese ziemlich vage Antwort bekam einige upvotes, ich fühle die Notwendigkeit, klar zu machen, dass meine Linked-List-Ansatz ein mögliches Beispiel ist. Wie im Kommentar erwähnt, sind Pythons Listen arrayähnlicher (und definitiv nicht verknüpfte Listen). Aber das Wichtigste ist: list.append() in python ist fast (amortized: O (1)), während das für numpy-arrays nicht gilt! Es gibt auch einen kleinen Teil über die Einbauten im docs:
Wie implementiert Listen?
Pythons Listen sind Arrays mit variabler Länge, keine verketteten Listen im Lisp-Stil. Die Implementierung verwendet ein zusammenhängendes Array von Referenzen auf andere Objekte und behält einen Zeiger auf dieses Array und die Länge des Arrays in einer Listenkopfstruktur.
Dies macht die Indizierung einer Liste zu einem [i] Vorgang, dessen Kosten unabhängig von der Größe der Liste oder dem Wert des Index sind.
Wenn Elemente angefügt oder eingefügt werden, wird das Array der Referenzen in der Größe geändert. Einige Klugheit wird angewandt, um die Leistung von anhängendem Artikel wiederholt zu verbessern; Wenn das Array vergrößert werden muss, wird zusätzlicher Speicherplatz zugewiesen, sodass die nächsten Male keine tatsächliche Größenänderung erforderlich sind.
(fett Anmerkungen von mir)
Es auf das, was New_Rows[i]
abhängig ist, und welche Art von Array tun Sie wollen. Wenn Sie mit Listen (oder 1D-Arrays) beginnen, die Sie Ende an Ende verbinden möchten (um ein langes 1d-Array zu erstellen), verketten Sie sie alle auf einmal. Verketten nimmt eine Liste beliebiger Länge, nicht nur 2 Elemente.
np.concatenate(New_Rows, axis=0)
oder vielleicht ein Zwischen Liste Verständnis verwenden (für mehr Flexibilität)
np.concatenate([row for row in New_Rows])
oder näher an Ihr Beispiel.
np.concatenate([New_Rows[i] for i in range(1000)])
Aber wenn New_Rows
Elemente alle die gleiche Länge haben, und Sie möchten ein 2D-Array, ein New_Rows
Wert pro Zeile, np.array
ist eine schöne Aufgabe:
np.array(New_Rows)
np.array([i for i in New_Rows])
np.array([New_Rows[i] for i in range(1000)])
np.array
ist in erster Linie ein bauen Array aus einer Liste von Listen.
np.concatenate
kann auch in 2d bauen, aber die Eingänge müssen 2d sein, um mit zu beginnen. vstack
und stack
können dafür sorgen. Aber alle diese stack
Funktionen verwenden eine Art Listenverständnis gefolgt von concatenate
.
Im Allgemeinen ist es besser/schneller, mit Listen zu iterieren oder anzufügen und die np.array
(oder verketten) nur einmal anzuwenden. appending
zu einer Liste ist schnell; viel schneller als ein neues Array zu erstellen.
Ich habe tatsächlich die Liste angehängt und die Leistung ist erheblich gesteigert. – Admia
Beachten Sie, dass Pythons '' 'liste''' eigentlich ein Array (intern) ist. Es wird sicherlich einige Tricks machen, wie das Reservieren von leeren Slots während des Wachstums und eine gute amortisierte Komplexität, aber eine klassische Linked-List könnte sogar noch schneller sein (abhängig von vielen Faktoren). – sascha
Python hat keine native verknüpfte Listenklasse. – hpaulj