Initialisieren Sie ein Numpy-Array

129

Gibt es eine Möglichkeit, ein numpy-Array einer Form zu initialisieren und zu ergänzen? Ich werde anhand eines Listenbeispiels erklären, was ich brauche. Wenn ich eine Liste von Objekten erstellen möchte, die in einer Schleife generiert wurden, kann ich Folgendes tun:

a = []
for i in range(5):
    a.append(i)

Ich möchte etwas Ähnliches mit einem numpy Array machen. Ich weiß über vstack, verketten usw. Es scheint jedoch, dass diese zwei numpy Arrays als Eingaben erfordern. Was ich brauche ist:

big_array # Initially empty. This is where I don't know what to specify
for i in range(5):
    array i of shape = (2,4) created.
    add to big_array

Die big_arraysollten eine Form haben (10,4). Wie macht man das?


BEARBEITEN:

Ich möchte die folgende Klarstellung hinzufügen. Mir ist bewusst, dass ich es definieren big_array = numpy.zeros((10,4))und dann auffüllen kann. Dies erfordert jedoch die vorherige Angabe der Größe von big_array. Ich kenne die Größe in diesem Fall, aber was ist, wenn ich es nicht tue? Wenn wir die .appendFunktion zum Erweitern der Liste in Python verwenden, müssen wir die endgültige Größe nicht im Voraus kennen. Ich frage mich, ob es etwas Ähnliches gibt, um ein größeres Array aus kleineren Arrays zu erstellen, beginnend mit einem leeren Array.

Curious2learn
quelle
Übrigens kann Ihr erstes Codebeispiel als Listenverständnis ordentlich und prägnant geschrieben werden : [i for i in range(5)]. (Entsprechend: list(range(5))obwohl dies ein erfundenes Beispiel ist.)
Katriel
Welche Lösung hat bei Ihnen funktioniert? Ich versuche, etwas Ähnliches zu tun, wie x = numpy.array()wir es mit einer Liste wie tun würden y = []. aber es hat nicht funktioniert
kRazzy R

Antworten:

160

numpy.zeros

Gibt ein neues Array mit einer bestimmten Form und einem bestimmten Typ zurück, das mit Nullen gefüllt ist.

oder

numpy.ones

Geben Sie ein neues Array mit einer bestimmten Form und einem bestimmten Typ zurück, das mit Einsen gefüllt ist.

oder

numpy.empty

Gibt ein neues Array mit der angegebenen Form und dem angegebenen Typ zurück, ohne Einträge zu initialisieren.


Die Mentalität, in der wir ein Array durch Anhängen von Elementen an eine Liste erstellen, wird in numpy jedoch nicht häufig verwendet, da sie weniger effizient ist (numpy-Datentypen liegen viel näher an den zugrunde liegenden C-Arrays). Stattdessen sollten Sie das Array der Größe zuordnen, die Sie benötigen, und dann die Zeilen ausfüllen. Sie können es jedoch verwenden, numpy.appendwenn Sie müssen.

Katriel
quelle
2
Ich weiß, dass ich big_array = numpy.zeros setzen und es dann mit den kleinen erstellten Arrays füllen kann. Dies erfordert jedoch, dass ich die Größe von big_array im Voraus spezifiziere. Gibt es nichts Vergleichbares wie .append der Listenfunktion, bei der ich die Größe nicht im Voraus angeben muss? Vielen Dank!
Curious2learn
2
@ Curious2learn. Nein, es gibt nichts Vergleichbares in Numpy. Es gibt Funktionen, die Arrays verketten oder durch Erstellen neuer Arrays stapeln, jedoch nicht durch Anhängen. Dies liegt an der Art und Weise, wie die Datenstrukturen eingerichtet sind. Numpy Arrays sind schnell, da sie Werte kompakter speichern können. Sie müssen jedoch eine feste Größe haben, um diese Geschwindigkeit zu erreichen. Python-Listen sind so konzipiert, dass sie auf Kosten von Geschwindigkeit und Größe flexibler sind.
Justin Peel
3
@Curious: Nun, es gibt eine appendAnzahl. Es ist nur weniger effizient, keine Vorbelegung vorzunehmen (in diesem Fall viel weniger effizient, da appendjedes Mal das gesamte Array kopiert wird), daher ist es keine Standardtechnik.
Katriel
1
Was ist, wenn nur ein Teil des np.emptyArrays mit Werten gefüllt ist? Was ist mit den verbleibenden "leeren" Gegenständen?
Lee
1
Wenn Sie nur die Breite kennen (zB benötigt für np.concatenate()), können Sie initialisieren mit : np.empty((0, some_width)). 0, also wird Ihr erstes Array kein Müll sein.
NumesSanguis
40

Normalerweise erstelle ich eine reguläre Liste, füge meine Daten hinzu und wandle die Liste schließlich wie folgt in ein numpy-Array um:

import numpy as np
big_array = [] #  empty regular list
for i in range(5):
    arr = i*np.ones((2,4)) # for instance
    big_array.append(arr)
big_np_array = np.array(big_array)  # transformed to a numpy array

Natürlich nimmt Ihr endgültiges Objekt beim Erstellungsschritt doppelt so viel Speicherplatz ein, aber das Anhängen an die Python-Liste ist sehr schnell und die Erstellung auch mit np.array ().

mad7777
quelle
11
Dies ist jedoch nicht der richtige Weg, wenn Sie die Größe des Arrays im Voraus kennen ... Ich verwende diese Methode häufig, wenn ich nicht weiß, wie groß das Array am Ende sein wird. Zum Beispiel beim Lesen von Daten aus einer Datei oder einem anderen Prozess. Es ist nicht wirklich so schrecklich, wie es zunächst scheinen mag, da Python und Numpy ziemlich klug sind.
travc
18

Eingeführt in numpy 1.8:

numpy.full

Gibt ein neues Array mit der angegebenen Form und dem angegebenen Typ zurück, das mit fill_value gefüllt ist.

Beispiele:

>>> import numpy as np
>>> np.full((2, 2), np.inf)
array([[ inf,  inf],
       [ inf,  inf]])
>>> np.full((2, 2), 10)
array([[10, 10],
       [10, 10]])
Franck Dernoncourt
quelle
13

Array-Analogon für die Pythons

a = []
for i in range(5):
    a.append(i)

ist:

import numpy as np

a = np.empty((0))
for i in range(5):
    a = np.append(a, i)
Adobe
quelle
5
@NicholasTJ: empty((0))Initialisiert ein Numpy-Array.
Adobe
2
Klammern in np.empty ((0)) sind redundant.
Szymon Roziewski
7

numpy.fromiter() ist was Sie suchen:

big_array = numpy.fromiter(xrange(5), dtype="int")

Es funktioniert auch mit Generatorausdrücken, z.

big_array = numpy.fromiter( (i*(i+1)/2 for i in xrange(5)), dtype="int" )

Wenn Sie die Länge des Arrays im Voraus kennen, können Sie es mit einem optionalen Argument 'count' angeben.

Quant Metropolis
quelle
2
Ich habe tatsächlich timeit ausgeführt und denke, dass np.fromiter () möglicherweise langsamer ist als np.array (). timeit ("np.array (i für i in xrange (100))", setup = "import numpy as np", number = 10000) -> 0.02539992332458496, versus timeit ("np.fromiter ((i für i in xrange ()) 100)), dtype = int) ", setup =" import numpy as np ", number = 10000) -> 0.13351011276245117
hlin117
6

Sie möchten explizite Schleifen beim Array-Computing so weit wie möglich vermeiden, da dies den Geschwindigkeitsgewinn bei dieser Form des Computing verringert. Es gibt mehrere Möglichkeiten, ein Numpy-Array zu initialisieren. Wenn Sie möchten, dass es mit Nullen gefüllt wird, tun Sie, was katrielalex sagte:

big_array = numpy.zeros((10,4))

EDIT: Was für eine Sequenz machst du? Sie sollten sich die verschiedenen Numpy-Funktionen ansehen, mit denen Arrays erstellt werden, z. B. numpy.linspace(start, stop, size)(Zahl mit gleichem Abstand) oder numpy.arange(start, stop, inc). Wenn möglich, machen diese Funktionen Arrays wesentlich schneller als die gleiche Arbeit in expliziten Schleifen

Andreas Løve Selvik
quelle
5

Verwenden Sie für Ihr erstes Array-Beispiel Folgendes:

a = numpy.arange(5)

Verwenden Sie zum Initialisieren von big_array

big_array = numpy.zeros((10,4))

Dies setzt voraus, dass Sie mit Nullen initialisieren möchten, was ziemlich typisch ist, aber es gibt viele andere Möglichkeiten, ein Array in numpy zu initialisieren .

Bearbeiten: Wenn Sie die Größe von big_array nicht im Voraus kennen, ist es im Allgemeinen am besten, zuerst eine Python-Liste mit append zu erstellen. Wenn Sie alles in der Liste gesammelt haben, konvertieren Sie diese Liste mit in ein numpy-Array numpy.array(mylist). Der Grund dafür ist, dass Listen sehr effizient und schnell wachsen sollen, während numpy.concatenate sehr ineffizient wäre, da sich die Größe von numpy-Arrays nicht leicht ändern lässt. Sobald jedoch alles in einer Liste zusammengefasst ist und Sie die endgültige Arraygröße kennen, kann ein Numpy-Array effizient erstellt werden.

tom10
quelle
5

So initialisieren Sie ein Numpy-Array mit einer bestimmten Matrix:

import numpy as np

mat = np.array([[1, 1, 0, 0, 0],
                [0, 1, 0, 0, 1],
                [1, 0, 0, 1, 1],
                [0, 0, 0, 0, 0],
                [1, 0, 1, 0, 1]])

print mat.shape
print mat

Ausgabe:

(5, 5)
[[1 1 0 0 0]
 [0 1 0 0 1]
 [1 0 0 1 1]
 [0 0 0 0 0]
 [1 0 1 0 1]]
edW
quelle
3

Wann immer Sie sich in der folgenden Situation befinden:

a = []
for i in range(5):
    a.append(i)

und Sie möchten etwas Ähnliches in numpy, mehrere frühere Antworten haben Wege aufgezeigt, dies zu tun, aber wie @katrielalex betonte, sind diese Methoden nicht effizient. Der effizienteste Weg, dies zu tun, besteht darin, eine lange Liste zu erstellen und sie dann nach einer langen Liste nach Ihren Wünschen umzugestalten. Nehmen wir zum Beispiel an, ich lese einige Zeilen aus einer Datei und jede Zeile enthält eine Liste von Zahlen. Ich möchte ein numpy-Array von Formen erstellen (Anzahl der gelesenen Zeilen, Länge des Vektors in jeder Zeile). So würde ich es effizienter machen:

long_list = []
counter = 0
with open('filename', 'r') as f:
    for row in f:
        row_list = row.split()
        long_list.extend(row_list)
        counter++
#  now we have a long list and we are ready to reshape
result = np.array(long_list).reshape(counter, len(row_list)) #  desired numpy array
Heapify
quelle
2

Mir ist klar, dass dies etwas spät ist, aber ich habe keine der anderen Antworten bemerkt, in denen die Indizierung in das leere Array erwähnt wird:

big_array = numpy.empty(10, 4)
for i in range(5):
    array_i = numpy.random.random(2, 4)
    big_array[2 * i:2 * (i + 1), :] = array_i

Auf diese Weise ordnen Sie das gesamte Ergebnisarray vorab zu numpy.emptyund füllen die Zeilen aus, während Sie die indizierte Zuweisung verwenden.

Es ist absolut sicher, eine Vorbelegung emptyanstelle des von zerosIhnen angegebenen Beispiels vorzunehmen, da Sie garantieren, dass das gesamte Array mit den von Ihnen generierten Blöcken gefüllt wird.

Verrückter Physiker
quelle
2

Ich würde vorschlagen, zuerst die Form zu definieren. Dann iteriere darüber, um Werte einzufügen.

big_array= np.zeros(shape = ( 6, 2 ))
for it in range(6):
    big_array[it] = (it,it) # For example

>>>big_array

array([[ 0.,  0.],
       [ 1.,  1.],
       [ 2.,  2.],
       [ 3.,  3.],
       [ 4.,  4.],
       [ 5.,  5.]])
GT GT
quelle
1

Vielleicht passt so etwas zu Ihren Bedürfnissen.

import numpy as np

N = 5
res = []

for i in range(N):
    res.append(np.cumsum(np.ones(shape=(2,4))))

res = np.array(res).reshape((10, 4))
print(res)

Welches erzeugt die folgende Ausgabe

[[ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]]

quelle