So fügen Sie einem leeren Numpy-Array eine neue Zeile hinzu

155

Mit Standard-Python-Arrays kann ich Folgendes tun:

arr = []
arr.append([1,2,3])
arr.append([4,5,6])
# arr is now [[1,2,3],[4,5,6]]

Allerdings kann ich nicht das Gleiche in Numpy tun. Beispielsweise:

arr = np.array([])
arr = np.append(arr, np.array([1,2,3]))
arr = np.append(arr, np.array([4,5,6]))
# arr is now [1,2,3,4,5,6]

Ich habe auch nachgesehen vstack, aber wenn ich vstackein leeres Array verwende, bekomme ich:

ValueError: all the input array dimensions except for the concatenation axis must match exactly

Wie füge ich eine neue Zeile in numpy an ein leeres Array an?

Tony Stark
quelle
1
Wenn es leer ist, warum dann? Beginnen Sie einfach mit einem Array, das nur die erste Zeile enthält.
Jonrsharpe
10
Ich möchte nur wissen, ob es möglich ist, an ein leeres numpy-Array anzuhängen. Manchmal ist es sauberer, Code wie diesen zu schreiben, da sich die Anhängeoperationen in einer Schleife befinden.
Tony Stark
5
In Anbetracht der Funktionsweise von Numpy-Arrays ist es viel besser, ein leeres Array zu erstellen, als die Daten einzugeben
jonrsharpe

Antworten:

224

Der Weg, um das gewünschte Array zu "starten", ist:

arr = np.empty((0,3), int)

Welches ist ein leeres Array, aber es hat die richtige Dimensionalität.

>>> arr
array([], shape=(0, 3), dtype=int64)

Stellen Sie dann sicher, dass Sie entlang der Achse 0 anhängen:

arr = np.append(arr, np.array([[1,2,3]]), axis=0)
arr = np.append(arr, np.array([[4,5,6]]), axis=0)

Aber @jonrsharpe ist richtig. Wenn Sie in einer Schleife anhängen, ist es viel schneller, wie in Ihrem ersten Beispiel an eine Liste anzuhängen und am Ende in ein Numpy-Array zu konvertieren, da Sie Numpy wirklich nicht als verwenden beabsichtigt während der Schleife:

In [210]: %%timeit
   .....: l = []
   .....: for i in xrange(1000):
   .....:     l.append([3*i+1,3*i+2,3*i+3])
   .....: l = np.asarray(l)
   .....: 
1000 loops, best of 3: 1.18 ms per loop

In [211]: %%timeit
   .....: a = np.empty((0,3), int)
   .....: for i in xrange(1000):
   .....:     a = np.append(a, 3*i+np.array([[1,2,3]]), 0)
   .....: 
100 loops, best of 3: 18.5 ms per loop

In [214]: np.allclose(a, l)
Out[214]: True

Die numpythonische Vorgehensweise hängt von Ihrer Anwendung ab, aber es wäre eher so:

In [220]: timeit n = np.arange(1,3001).reshape(1000,3)
100000 loops, best of 3: 5.93 µs per loop

In [221]: np.allclose(a, n)
Out[221]: True
askewchan
quelle
Was ist, wenn ich dies 10 ^ 5 oder 10 ^ 6 Mal tun muss? es scheint, dass keine dieser Methoden gelten wird. irgendein Vorschlag?
Rho Phi
@Roberto, normalerweise gibt es eine Möglichkeit, die Größe oder Form (zumindest Werte wären vorzuziehen) des Arrays im Voraus zu bestimmen. Glaubst du, du kannst das? Das Anhängen sollte wirklich eine ein- oder zweimalige Operation sein.
Askewchan
Manchmal kann man die Dimensionen nicht erraten, es ist das Leben. Sie können jedoch ein ausreichend großes Array zuweisen und seinen Ansichten Werte zuweisen. Ich mag es aber nicht, weil es unerwünschte Werte gibt, die man finden muss, um zu "maskieren". Diese Idee der Maskierung passt wirklich nicht zu meinem Geschmack.
Rho Phi
Keine Notwendigkeit zu maskieren, nur in Scheiben schneiden! a = a[:N] Obwohl ich der festen Überzeugung bin, dass Sie einen Weg finden sollten, dies zu vektorisieren (stellen Sie eine neue Frage mit Ihren Angaben, wenn Sie Hilfe benötigen) oder einfach Listen verwenden sollten, bis die Schleife beendet ist.
Askewchan
29

Hier ist meine Lösung:

arr = []
arr.append([1,2,3])
arr.append([4,5,6])
np_arr = np.array(arr)
just4fun
quelle
Das resultierende Array hat einen Objekttyp dt, was in bestimmten Fällen nicht akzeptabel ist
zer0fool
26

In diesem Fall möchten Sie möglicherweise die Funktionen np.hstack und np.vstack verwenden

arr = np.array([])
arr = np.hstack((arr, np.array([1,2,3])))
# arr is now [1,2,3]

arr = np.vstack((arr, np.array([4,5,6])))
# arr is now [[1,2,3],[4,5,6]]

Sie können auch die Funktion np.concatenate verwenden.

Prost

mrcl
quelle
7
Funktioniert nicht, wenn das zweite Array eine Dimension> = 2 hat ((2, 2)). Es scheint mir, dass es keine Möglichkeit gibt, Grenzfälle zu vermeiden, wenn Sie durch Verkettung leere Arrays aufbauen.
Taozi
Keine gute Lösung, da jedes Mal die Abmessung überprüft werden muss.
SKR
1

Bei Verwendung einer benutzerdefinierten dtype-Definition funktionierte für mich Folgendes:

import numpy

# define custom dtype
type1 = numpy.dtype([('freq', numpy.float64, 1), ('amplitude', numpy.float64, 1)])
# declare empty array, zero rows but one column
arr = numpy.empty([0,1],dtype=type1)
# store row data, maybe inside a loop
row = numpy.array([(0.0001, 0.002)], dtype=type1)
# append row to the main array
arr = numpy.row_stack((arr, row))
# print values stored in the row 0
print float(arr[0]['freq'])
print float(arr[0]['amplitude'])
Boclodoa
quelle
1

Wenn Sie neue Zeilen für das Array in der Schleife hinzufügen, weisen Sie das Array direkt zum ersten Mal in der Schleife zu, anstatt ein leeres Array zu initialisieren.

for i in range(0,len(0,100)):
    SOMECALCULATEDARRAY = .......
    if(i==0):
        finalArrayCollection = SOMECALCULATEDARRAY
    else:
        finalArrayCollection = np.vstack(finalArrayCollection,SOMECALCULATEDARRAY)

Dies ist hauptsächlich nützlich, wenn die Form des Arrays unbekannt ist

Rajesh_Saladi
quelle
0

Ich möchte eine for-Schleife machen, aber mit der Methode von askewchan funktioniert sie nicht gut, deshalb habe ich sie geändert.

x=np.empty((0,3))
y=np.array([1 2 3])
for i in ...
x = vstack((x,y))
Qingdong Wang
quelle