- vs - = операторы с numpy
У меня есть странное поведение в моем коде на Python, связанном с -
и -=
. Я пишу декомпозицию QR, используя numpy, и имею следующую строку кода в двойном цикле:
v = v - r[i,j] * q[:,i]
где q
и r
равны numpy.array
, а v
- это фрагмент другого numpy.array
, взятый как v = x[:,j]
.
Приведенный выше код не работает должным образом во всех случаях. Однако, если я сделаю следующее изменение:
v -= r[i,j] * q[:,i]
Затем все работает безупречно.
У меня создалось впечатление, что эти две строки должны быть одинаковыми. Чтобы проверить, работают ли -=
и _ = _ -
, я создал следующий фрагмент
import numpy
x = numpy.array(range(0,6))
y = numpy.array(range(0,6))
u = x[3:5]
v = y[3:5]
print u,v
u = u - [1,1]
v -= [1,1]
print u,v
который снова работает так, как ожидалось, создавая [2 3] [2 3]
для обоих операторов печати.
Поэтому я совершенно смущен, почему эти две линии работают по-другому. Единственная возможная вещь, о которой я могу думать, это то, что иногда я имею дело с чрезвычайно маленькими числами (порядка 10 ^ -8 или меньше), и есть ли какая-то точность, с которой -=
лучше? Первая строка ухудшается по мере уменьшения элементов x
.
Я прошу прощения, если есть какие-либо другие сообщения об этой аналогичной проблеме, я не могу найти -
и -=
, и я не знаю, есть ли какие-либо правильные условия для них помимо присваивания/операторов.
Спасибо за любую помощь!
Ответы
Ответ 1
Когда v
- это срез, то v -= X
и v = v - X
дают очень разные результаты. Рассмотрим
>>> x = np.arange(6)
>>> v = x[1:4]
>>> v -= 1
>>> v
array([0, 1, 2])
>>> x
array([0, 0, 1, 2, 4, 5])
где v -= 1
обновляет срез и, следовательно, массив, который он просматривает, на месте, vs.
>>> x = np.arange(6)
>>> v = x[1:4]
>>> v = v - 1
>>> v
array([0, 1, 2])
>>> x
array([0, 1, 2, 3, 4, 5])
где v = v - 1
сбрасывает переменную v
, оставляя x
нетронутой. Чтобы получить прежний результат без -=
, вам нужно будет сделать
v[:] = v - 1
Ответ 2
Вы можете получить разные результаты от x - y
и x -= y
, если разные типы данных x
и y
отличаются.
Например:
import numpy as np
x = np.array(range(0,6))
y = np.array(np.arange(0,3,0.5))
print x - y
x -= y
print x
Это выдает:
[ 0. 0.5 1. 1.5 2. 2.5]
[0 0 1 1 2 2]
Возможно, стоит убедиться, что ваши массивы dtypes
точно такие, как вы ожидаете (например, вы не случайно используете массивы integer или float32
вместо float64
), обращая особое внимание на массивы, используемые слева -сторонняя сторона -=
.
Ответ 3
+1 для обоих ответов на эти вопросы. Они охватывают два важных различия между =
и -=
, но я хотел выделить еще один. В большинстве случаев x -= y
совпадает с x[:] = x - y
, но не тогда, когда x
и y
являются срезами одного и того же массива. Например:
x = np.ones(10)
y = np.ones(10)
x[1:] += x[:-1]
print x
[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
y[1:] = y[1:] + y[:-1]
print y
[ 1. 2. 2. 2. 2. 2. 2. 2. 2. 2.]