array python numpy iterator

array - ¿Qué significa "tres puntos" en Python al indexar lo que parece un número?



iterate numpy array (1)

¿Cuál es el significado de x [...] a continuación?

a = np.arange(6).reshape(2,3) for x in np.nditer(a, op_flags=[''readwrite'']): x[...] = 2 * x


Mientras que el duplicado propuesto ¿Qué hace el objeto Elipsis de Python? responde la pregunta en un contexto general de python , su uso en un bucle nditer requiere, creo, información adicional.

https://docs.scipy.org/doc/numpy/reference/arrays.nditer.html#modifying-array-values

La asignación regular en Python simplemente cambia una referencia en el diccionario de variables locales o globales en lugar de modificar una variable existente en su lugar. Esto significa que simplemente asignar a x no colocará el valor en el elemento de la matriz, sino que cambiará de ser una referencia de elemento de matriz a una referencia al valor que asignó. Para modificar realmente el elemento de la matriz, x debe indexarse ​​con puntos suspensivos.

Esa sección incluye su ejemplo de código.

Entonces, en mis palabras, la x[...] = ... modifica x en el lugar; x = ... habría roto el enlace a la variable nditer , y no lo nditer cambiado. Es como x[:] = ... pero funciona con matrices de cualquier dimensión (incluido 0d). En este contexto, x no es solo un número, es una matriz.

Quizás lo más parecido a esta iteración de nditer , sin nditer es:

In [667]: for i, x in np.ndenumerate(a): ...: print(i, x) ...: a[i] = 2 * x ...: (0, 0) 0 (0, 1) 1 ... (1, 2) 5 In [668]: a Out[668]: array([[ 0, 2, 4], [ 6, 8, 10]])

Tenga en cuenta que tuve que indexar y modificar a[i] directamente. No podría haber usado, x = 2*x . En esta iteración, x es un escalar y, por lo tanto, no mutable

In [669]: for i,x in np.ndenumerate(a): ...: x[...] = 2 * x ... TypeError: ''numpy.int32'' object does not support item assignment

Pero en el caso nditer x es una matriz 0d, y mutable.

In [671]: for x in np.nditer(a, op_flags=[''readwrite'']): ...: print(x, type(x), x.shape) ...: x[...] = 2 * x ...: 0 <class ''numpy.ndarray''> () 4 <class ''numpy.ndarray''> () ...

Y como es 0d, x[:] no se puede usar en lugar de x[...]

----> 3 x[:] = 2 * x IndexError: too many indices for array

Una iteración de matriz más simple también podría dar una idea:

In [675]: for x in a: ...: print(x, x.shape) ...: x[:] = 2 * x ...: [ 0 8 16] (3,) [24 32 40] (3,)

esto itera en las filas (primer dim) de a . x es entonces una matriz 1d, y se puede modificar con x[:]=... o x[...]=...

Y si agrego el indicador external_loop de la siguiente section , x ahora es una matriz 1d, y x[:] = funcionaría. Pero x[...] = todavía funciona y es más general. x[...] se utiliza todos los otros ejemplos de nditer .

In [677]: for x in np.nditer(a, op_flags=[''readwrite''], flags=[''external_loop'']): ...: print(x, type(x), x.shape) ...: x[...] = 2 * x [ 0 16 32 48 64 80] <class ''numpy.ndarray''> (6,)

Compare esta simple iteración de fila (en una matriz 2d):

In [675]: for x in a: ...: print(x, x.shape) ...: x[:] = 2 * x ...: [ 0 8 16] (3,) [24 32 40] (3,)

esto itera en las filas (primer dim) de a . x es entonces una matriz 1d, y se puede modificar con x[:] = ... o x[...] = ...

Lea y experimente con esta página de nditer hasta el final. Por sí solo, nditer no es tan útil en python . No acelera la iteración, no hasta que cython su código a cython . np.ndindex es una de las pocas funciones numpy no compiladas que usa nditer .