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, aa 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:
ato 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 ana [1, 1, 3]. Teraz mamy a[1:]to widok danych [1, 3], a a[:-1]jest to widok danych [1, 1](drugi element tablicy azostał 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].
ajest 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 bsię 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ą outparametru w funkcji uniwersalnych (jak np.subtracti np.multiply), aby odpisać na jednej z tablic.