Ich muss ein NumPy-Array mit einer Länge erstellen n
, von denen jedes Element ist v
.
Gibt es etwas Besseres als:
a = empty(n)
for i in range(n):
a[i] = v
Ich weiß zeros
und ones
würde für v = 0, 1 arbeiten. Ich könnte verwenden v * ones(n)
, aber es wird nicht funktionieren, wenn es wäre auch viel langsamer.v
ist None
, und
a = np.zeros(n)
in der Schleife für den Fall 0 schneller alsa.fill(0)
. Dies widerspricht meinen Erwartungen, da ich dachte, icha=np.zeros(n)
müsste neuen Speicher zuweisen und initialisieren. Wenn jemand dies erklären kann, würde ich es schätzen.v * ones(n)
ist es immer noch schrecklich, da es die teure Multiplikation verwendet. Ersetzen Sie es*
durch+
und esv + zeros(n)
stellt sich in einigen Fällen als überraschend gut heraus ( stackoverflow.com/questions/5891410/… ).var = np.empty(n)
und dann mit 'var [:] = v' zu füllen. (Übrigensnp.full()
ist so schnell)Antworten:
NumPy 1.8 wurde eingeführt. Dies
np.full()
ist eine direktere Methode als dieempty()
folgende,fill()
um ein Array mit einem bestimmten Wert zu erstellen:Dies ist wohl die Art und Weise, ein Array mit bestimmten Werten zu erstellen, da es explizit beschreibt, was erreicht wird (und im Prinzip sehr effizient sein kann, da es eine sehr spezifische Aufgabe ausführt).
quelle
help(numpy.full)
in einer Python-Shell tun . Ich bin auch überrascht, dass es nicht in der Webdokumentation steht.np.fill()
existiert nicht und sollte es seinarr.fill()
), mit einem Unterschied von ungefähr 10%. Wenn der Unterschied größer wäre, würde ich ein Problem im NumPy-Bug-Tracker ansprechen. :) Ich bevorzuge expliziteren und klareren Code für einen so kleinen Unterschied in der Ausführungszeit, also gehe ich dienp.full()
ganze Zeit mit.Aktualisiert für Numpy 1.7.0: (Hutspitze zu @Rolf Bartstra.)
a=np.empty(n); a.fill(5)
ist am schnellsten.In absteigender Geschwindigkeitsreihenfolge:
quelle
np.full()
wäre nützlich. Auf meinem Computer ist es mit NumPy 1.8.1 etwa 15% langsamer als die weniger direktefill()
Version (was unerwartetfull()
ist und das Potenzial hat, etwas schneller zu werden).fill()
ist die schnellste Lösung. Die Multiplikationslösung ist viel langsamer.10000
anstelle von1e4
aus irgendeinem Grund einen spürbaren Unterschied (full()
ist mit fast 50% langsamer1e4
).full()
Wenn ich nur meine Ergebnisse mit hinzufüge , läuft es erheblich langsamer, wenn der Datentyp nicht explizit ein Float ist. Ansonsten ist es mit den besten Methoden hier vergleichbar (aber etwas langsamer).full(100000, 5)
,full(100000, 5, dtype=float)
,full(100000, 5, dtype=int)
unda =np.empty(100000); a.fill(5)
alle nehmen etwa zur gleichen Zeit auf meinem Rechner (ohne Caching:%timeit -r1 -n1 …
) (NumPy 1.11.2).Ich glaube, das
fill
ist der schnellste Weg, dies zu tun.Sie sollten auch immer vermeiden, wie in Ihrem Beispiel zu iterieren. Mit einer einfachen Funktion
a[:] = v
können Sie mithilfe von Numpy Broadcasting erreichen, was Ihre Iteration bewirkt .quelle
fill
sah ich, dass dasrepeat
meinen Bedürfnissen noch besser entspricht.a[:]=v
insgesamt tatsächlich schneller ist als diefill
?fill
.Offenbar nicht nur die absoluten Geschwindigkeiten , sondern auch die Geschwindigkeit , um (wie durch user1579844 berichtete) sind maschinenabhängig; Folgendes habe ich gefunden:
a=np.empty(1e4); a.fill(5)
ist am schnellsten;In absteigender Geschwindigkeitsreihenfolge:
Versuchen Sie also herauszufinden, was auf Ihrer Plattform am schnellsten ist.
quelle
ich hatte
im Kopf, aber anscheinend ist das langsamer als alle anderen Vorschläge für groß genug
n
.Hier ist ein vollständiger Vergleich mit Perfplot (einem meiner Lieblingsprojekte ).
Die beiden
empty
Alternativen sind immer noch die schnellsten (mit NumPy 1.12.1).full
holt große Arrays ein.Code zum Generieren des Plots:
quelle
Sie können
numpy.tile
zB verwenden:Obwohl
tile
ein Array "kacheln" soll (anstelle eines Skalars, wie in diesem Fall), erledigt es die Aufgabe und erstellt vorgefüllte Arrays beliebiger Größe und Dimension.quelle
ohne numpy
quelle
[v] * n
wären für die OP-Frage direkter relevant.