Mientras que el duplicado propuesto ¿Qué hace el objeto Python Ellipsis? responde a la pregunta en un pythoncontexto general , su uso en un nditerbucle requiere, creo, información adicional.
La asignación regular en Python simplemente cambia una referencia en el diccionario de variable local o global en lugar de modificar una variable existente en su lugar. Esto significa que simplemente asignar ax no colocará el valor en el elemento de la matriz, sino que cambiará x de ser una referencia de elemento de matriz a ser 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, las x[...] = ...modificaciones xen el lugar; x = ...habría roto el enlace a la nditervariable y no lo habría cambiado. Es como, x[:] = ...pero funciona con matrices de cualquier dimensión (incluido 0d). En este contexto, xno es solo un número, es una matriz.
Quizás lo más cercano a esta nditeriteración, sin nditeres:
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]])
Observe que tuve que indexar y modificar a[i]directamente. No podría haber usado x = 2*x,. En esta iteración xes un escalar y, por lo tanto, no es 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 nditercaso xes 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 debido a que es 0d, x[:]no se puede usar en lugar dex[...]
----> 3 x[:] = 2 * x
IndexError: too many indices for array
Una iteración de matriz más simple también podría brindar información:
In [675]: for x in a:
...: print(x, x.shape)
...: x[:] = 2 * x
...:
[ 0816] (3,)
[243240] (3,)
esto itera en las filas (primera atenuación) de a. xes entonces una matriz 1d y se puede modificar con x[:]=...o x[...]=....
Y si agrego la external_loopbandera de la siguiente sección , xahora es una matriz 1d y x[:] =funcionaría. Pero x[...] =todavía funciona y es más general. x[...]se utiliza todos los demás nditerejemplos.
In [677]: for x in np.nditer(a, op_flags=['readwrite'], flags=['external_loop']):
...: print(x, type(x), x.shape)
...: x[...] = 2 * x
[ 01632486480] <class 'numpy.ndarray'> (6,)
Compare esta iteración de fila simple (en una matriz 2d):
In [675]: for x in a:
...: print(x, x.shape)
...: x[:] = 2 * x
...:
[ 0816] (3,)
[243240] (3,)
esto itera en las filas (primera atenuación) de a. xes entonces una matriz 1d y se puede modificar con x[:] = ...o x[...] = ....
Lea y experimente con esta nditerpágina hasta el final. Por sí solo, nditerno es tan útil en python. No acelera la iteración, no hasta que transfiera su código a cython. np.ndindexes una de las pocas numpyfunciones no compiladas que utiliza nditer.
Respuestas:
Mientras que el duplicado propuesto ¿Qué hace el objeto Python Ellipsis? responde a la pregunta en un
pythoncontexto general , su uso en unnditerbucle requiere, creo, información adicional.https://docs.scipy.org/doc/numpy/reference/arrays.nditer.html#modifying-array-values
Esa sección incluye su ejemplo de código.
Entonces, en mis palabras, las
x[...] = ...modificacionesxen el lugar;x = ...habría roto el enlace a landitervariable y no lo habría cambiado. Es como,x[:] = ...pero funciona con matrices de cualquier dimensión (incluido 0d). En este contexto,xno es solo un número, es una matriz.Quizás lo más cercano a esta
nditeriteración, sinnditeres: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]])Observe que tuve que indexar y modificar
a[i]directamente. No podría haber usadox = 2*x,. En esta iteraciónxes un escalar y, por lo tanto, no es mutableIn [669]: for i,x in np.ndenumerate(a): ...: x[...] = 2 * x ... TypeError: 'numpy.int32' object does not support item assignmentPero en el
nditercasoxes 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 debido a que es 0d,
x[:]no se puede usar en lugar dex[...]----> 3 x[:] = 2 * x IndexError: too many indices for arrayUna iteración de matriz más simple también podría brindar información:
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 (primera atenuación) de
a.xes entonces una matriz 1d y se puede modificar conx[:]=...ox[...]=....Y si agrego la
external_loopbandera de la siguiente sección ,xahora es una matriz 1d yx[:] =funcionaría. Perox[...] =todavía funciona y es más general.x[...]se utiliza todos los demásnditerejemplos.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 iteración de fila simple (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 (primera atenuación) de
a.xes entonces una matriz 1d y se puede modificar conx[:] = ...ox[...] = ....Lea y experimente con esta
nditerpágina hasta el final. Por sí solo,nditerno es tan útil enpython. No acelera la iteración, no hasta que transfiera su código acython.np.ndindexes una de las pocasnumpyfunciones no compiladas que utilizanditer.fuente