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
.