2011-08-06 13 views
96

¿Hay una alternativa menos detallado a esto:interactuando sobre una matriz numpy

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

me ocurrió esto:

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

lo que ahorra una muesca, pero sigue siendo bastante fea.

que estoy esperando algo que se parece a esto pseudocódigo:

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

¿Existe algo así?

Respuesta

138

Creo que está buscando ndenumerate.

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

En cuanto al rendimiento. Es un poco más lento que una lista de comprensión.

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 

Si usted está preocupado por el rendimiento que podría optimizar un poco más mirando a la implementación de ndenumerate, que hace 2 cosas, la conversión a una matriz y un bucle. Si sabe que tiene una matriz, puede llamar al atributo .coords del iterador plano.

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

Tenga en cuenta que esto funciona pero es increíblemente lento. Es mejor iterar manualmente. – Marty

35

Si sólo necesita los índices, podría intentar 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)] 
9

ver 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 = 3 no quiere trabajar, utilizar y *= 0 y y += 3 lugar.

+0

o use y [...] = 3 –

Cuestiones relacionadas