Uwaga: używanie operacji w miejscu na tablicach NumPy, które współużytkują pamięć, nie stanowi już problemu w wersji 1.13.0 i nowszych (zobacz szczegóły tutaj ). Te dwie operacje dadzą ten sam wynik. Ta odpowiedź dotyczy tylko wcześniejszych wersji NumPy.
Mutowanie tablic, gdy są używane w obliczeniach, może prowadzić do nieoczekiwanych wyników!
W przykładzie w pytaniu odejmowanie za pomocą -=
modyfikuje drugi element programu, a
a następnie natychmiast używa tego zmodyfikowanego drugiego elementu w operacji na trzecim elemencie programu a
.
Oto, co dzieje się a[1:] -= a[:-1]
krok po kroku:
a
to tablica z danymi [1, 2, 3]
.
Mamy dwa poglądy na te dane: a[1:]
jest [2, 3]
i a[:-1]
jest [1, 2]
.
Rozpoczyna się odejmowanie w miejscu -=
. Pierwszy element a[:-1]
1 jest odejmowany od pierwszego elementu a[1:]
. To zostało zmienione a
na [1, 1, 3]
. Teraz mamy a[1:]
to widok danych [1, 3]
, a a[:-1]
jest to widok danych [1, 1]
(drugi element tablicy a
został zmieniony).
a[:-1]
jest teraz [1, 1]
i NumPy musi teraz odjąć drugi element, który wynosi 1 (już nie 2!) od drugiego elementu a[1:]
. To daje a[1:]
pogląd na wartości [1, 2]
.
a
jest teraz tablicą zawierającą wartości [1, 1, 2]
.
b[1:] = b[1:] - b[:-1]
nie ma tego problemu, ponieważ najpierw b[1:] - b[:-1]
tworzy nową tablicę, a następnie przypisuje wartości w tej tablicy do b[1:]
. Nie modyfikuje b
się podczas odejmowania, więc widoki b[1:]
i b[:-1]
nie zmieniają się.
Ogólna rada jest taka, aby unikać modyfikowania jednego widoku w miejscu innym, jeśli się pokrywają. Obejmuje operatorów -=
, *=
itp i za pomocą out
parametru w funkcji uniwersalnych (jak np.subtract
i np.multiply
), aby odpisać na jednej z tablic.