- против - = операторы с NumPy - PullRequest
13 голосов
/ 28 января 2012

У меня странное поведение в коде 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 становятся меньше.

Я прошу прощения, если есть какие-либо другие сообщения об этой аналогичной проблеме, я не могу искать - и -=, и я не знаю, есть ли какие-либо правильные термины для них, кроме присвоения / операторов.

Спасибо за любую помощь!

Ответы [ 3 ]

22 голосов
/ 28 января 2012

Когда 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 обновляет срез, и, следовательно, массив, который он просматривает, на месте, против

>>> 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
12 голосов
/ 28 января 2012

Вы можете получить разные результаты от 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

Это печатаетout:

[ 0.   0.5  1.   1.5  2.   2.5]
[0 0 1 1 2 2]

Возможно, стоит убедиться, что значения dtypes ваших массивов точно соответствуют вашим ожиданиям (например, вы не случайно используете целочисленные или float32 массивы вместо float64), заплативособое внимание к массивам, используемым в левой части -=.

5 голосов
/ 28 января 2012

+ 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.]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...