Iterieren über ein numpy Array


135

Gibt es eine weniger ausführliche Alternative dazu:

for x in xrange(array.shape[0]):
    for y in xrange(array.shape[1]):
        do_stuff(x, y)

Ich habe mir das ausgedacht:

for x, y in itertools.product(map(xrange, array.shape)):
    do_stuff(x, y)

Das spart eine Einrückung, ist aber immer noch ziemlich hässlich.

Ich hoffe auf etwas, das wie dieser Pseudocode aussieht:

for x, y in array.indices:
    do_stuff(x, y)

Gibt es so etwas?


Ich bin in Python 2.7 und verwende Ihre Lösung mit den itertools. Ich habe in den Kommentaren gelesen, dass die Verwendung von itertools schneller sein wird. Allerdings (vielleicht weil ich in 2.7 bin) musste ich auch die Karte in der for-Schleife entpacken. for x, y in itertools.product(*map(xrange, array.shape)):
ALM

Es gibt eine Seite in der NumPy-Referenz mit dem Namen "Iterieren über Arrays": docs.scipy.org/doc/numpy/reference/arrays.nditer.html
Casey

Antworten:


187

Ich denke, Sie suchen die Zahl .

>>> a =numpy.array([[1,2],[3,4],[5,6]])
>>> for (x,y), value in numpy.ndenumerate(a):
...  print x,y
... 
0 0
0 1
1 0
1 1
2 0
2 1

In Bezug auf die Leistung. Es ist etwas langsamer als ein Listenverständnis.

X = np.zeros((100, 100, 100))

%timeit list([((i,j,k), X[i,j,k]) for i in range(X.shape[0]) for j in range(X.shape[1]) for k in range(X.shape[2])])
1 loop, best of 3: 376 ms per loop

%timeit list(np.ndenumerate(X))
1 loop, best of 3: 570 ms per loop

Wenn Sie sich Sorgen über die Leistung machen, können Sie ein wenig weiter optimieren, indem Sie sich die Implementierung von ansehen ndenumerate, die zwei Dinge bewirkt: Konvertieren in ein Array und Schleifen. Wenn Sie wissen, dass Sie ein Array haben, können Sie das .coordsAttribut des flachen Iterators aufrufen .

a = X.flat
%timeit list([(a.coords, x) for x in a.flat])
1 loop, best of 3: 305 ms per loop

1
Beachten Sie, dass dies funktioniert, aber unglaublich langsam ist. Sie sollten besser manuell iterieren.
Marty

43

Wenn Sie nur die Indizes benötigen, können Sie Folgendes versuchen numpy.ndindex:

>>> a = numpy.arange(9).reshape(3, 3)
>>> [(x, y) for x, y in numpy.ndindex(a.shape)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

15

siehe nditer

import numpy as np
Y = np.array([3,4,5,6])
for y in np.nditer(Y, op_flags=['readwrite']):
    y += 3

Y == np.array([6, 7, 8, 9])

y = 3würde nicht funktionieren, verwenden y *= 0und y += 3stattdessen.


2
oder benutze y [...] = 3
Donald Hobson
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.