Was bedeutet das x[...]
unten?
a = np.arange(6).reshape(2,3)
for x in np.nditer(a, op_flags=['readwrite']):
x[...] = 2 * x
Was bedeutet das x[...]
unten?
a = np.arange(6).reshape(2,3)
for x in np.nditer(a, op_flags=['readwrite']):
x[...] = 2 * x
Antworten:
Während des vorgeschlagenen Duplikats Was macht das Python Ellipsis-Objekt? beantwortet die Frage in einem allgemeinen python
Kontext, ihre Verwendung in einer nditer
Schleife erfordert, denke ich, zusätzliche Informationen.
https://docs.scipy.org/doc/numpy/reference/arrays.nditer.html#modifying-array-values
Durch die regelmäßige Zuweisung in Python wird einfach eine Referenz im lokalen oder globalen Variablenwörterbuch geändert, anstatt eine vorhandene Variable zu ändern. Dies bedeutet, dass durch einfaches Zuweisen zu x der Wert nicht in das Element des Arrays eingefügt wird, sondern dass x von einer Array-Elementreferenz zu einer Referenz auf den von Ihnen zugewiesenen Wert wechselt. Um das Element des Arrays tatsächlich zu ändern, sollte x mit den Auslassungspunkten indiziert werden.
Dieser Abschnitt enthält Ihr Codebeispiel.
In meinen Worten x[...] = ...
ändert sich das x
an Ort und Stelle; x = ...
hätte den Link zur nditer
Variablen unterbrochen und nicht geändert. Es ist wie x[:] = ...
, funktioniert aber mit Arrays jeder Dimension (einschließlich 0d). In diesem Zusammenhang x
ist es nicht nur eine Zahl, sondern ein Array.
Vielleicht ist das, was dieser nditer
Iteration am nächsten kommt , ohne nditer
:
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]])
Beachten Sie, dass ich a[i]
direkt indizieren und ändern musste . Ich hätte nicht benutzen können , x = 2*x
. In dieser Iteration x
ist ein Skalar und somit nicht veränderbar
In [669]: for i,x in np.ndenumerate(a):
...: x[...] = 2 * x
...
TypeError: 'numpy.int32' object does not support item assignment
In diesem nditer
Fall x
handelt es sich jedoch um ein 0d-Array, das veränderbar ist.
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'> ()
...
Und weil es 0d ist, x[:]
kann nicht anstelle von verwendet werdenx[...]
----> 3 x[:] = 2 * x
IndexError: too many indices for array
Eine einfachere Array-Iteration könnte auch Einblicke geben:
In [675]: for x in a:
...: print(x, x.shape)
...: x[:] = 2 * x
...:
[ 0 8 16] (3,)
[24 32 40] (3,)
Dies iteriert in den Zeilen (1. Abm.) von a
. x
ist dann ein 1d-Array und kann mit entweder x[:]=...
oder geändert werden x[...]=...
.
Und wenn ich das external_loop
Flag aus dem nächsten Abschnitt hinzufüge , x
ist es jetzt ein 1d-Array und x[:] =
würde funktionieren. Funktioniert aber x[...] =
immer noch und ist allgemeiner. x[...]
wird alle anderen nditer
Beispiele verwendet.
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,)
Vergleichen Sie diese einfache Zeileniteration (auf einem 2d-Array):
In [675]: for x in a:
...: print(x, x.shape)
...: x[:] = 2 * x
...:
[ 0 8 16] (3,)
[24 32 40] (3,)
Dies iteriert in den Zeilen (1. Abm.) von a
. x
ist dann ein 1d-Array und kann mit entweder x[:] = ...
oder geändert werden x[...] = ...
.
Lesen und experimentieren Sie mit dieser nditer
Seite bis zum Ende. An sich nditer
ist das nicht so nützlich in python
. Die Iteration wird nicht beschleunigt - erst, wenn Sie Ihren Code auf portieren cython
. np.ndindex
ist eine der wenigen nicht kompilierten numpy
Funktionen, die verwendet werden nditer
.