2016-07-19 12 views

Antwort

11

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).

  • Wenn Sie Ihre Daten bei np.array Schaffung Zeit bekommen, fügen Sie einfach diese alle auf einmal (Speicher nur einmal vergeben wird dann!)
  • Wenn nicht, sammelt sie mit so etwas wie eine verknüpften Liste (unter Berücksichtigung O (1) anhängende Operationen). Dann lies es in deinem np.array auf einmal (wieder nur eine Speicherzuweisung).

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)

+0

Ich habe tatsächlich die Liste angehängt und die Leistung ist erheblich gesteigert. – Admia

+0

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

+3

Python hat keine native verknüpfte Listenklasse. – hpaulj

3

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.

Verwandte Themen