2016-04-08 5 views
0

У меня есть два Numpy массивы формы (1, 250000):Weird поведение, когда возведение в квадрат элементов в Numpy массиве

a = [[ 0 254 1 ..., 255 0 1]] 
b = [[ 1 0 252 ..., 0 255 255]] 

Я хочу, чтобы создать новый Numpy массив, элементы которого квадратный корень из суммы квадратов элементов в массивах a и b, но я не получаю правильный результат:

>>> c = np.sqrt(np.square(a)+np.square(b)) 
>>> print c 
[[ 1.   2.   4.12310553 ..., 1.   1.   1.41421354]] 

я упускаю что-то простое здесь?

+1

Ваш пример на самом деле отлично работает для меня. 'Импорта NumPy, как np' ' а = [[0, 254, 1, 255, 0, 1]] '' Ь = [[1, 0, 252, 0, 255, 255]] ' 'c = np.sqrt (np.square (a) + np.square (b))' Выход: '[[1. 254. 252.00198412 255. 255. 255.00196078]]' Дополнительные квадратные скобки не нужны, но я оставил их на месте, чтобы показать свои прогоны кода, по крайней мере, с кратким примером. – roadrunner66

+2

Пожалуйста, всегда предоставляйте исполняемый файл, если вы можете (см. [MCVE]), чтобы люди могли сразу запустить вашу проблему. – roadrunner66

+0

Благодарим вас за отзыв! –

ответ

5

Предположительно, ваши массивы a и b являются массивами беззнаковых 8-битных целых чисел - вы можете проверить, проверив атрибут a.dtype. Когда вы умиротворять их, сохраняется тип данных, а также переполнение 8 бит значения, что означает, что значения «обтекать» (т.е. квадратичные значения по модулю 256):

In [7]: a = np.array([[0, 254, 1, 255, 0, 1]], dtype=np.uint8) 

In [8]: np.square(a) 
Out[8]: array([[0, 4, 1, 1, 0, 1]], dtype=uint8) 

In [9]: b = np.array([[1, 0, 252, 0, 255, 255]], dtype=np.uint8) 

In [10]: np.square(a) + np.square(b) 
Out[10]: array([[ 1, 4, 17, 1, 1, 2]], dtype=uint8) 

In [11]: np.sqrt(np.square(a) + np.square(b)) 
Out[11]: 
array([[ 1.  , 2.  , 4.12310553, 1.  , 1.  , 
     1.41421354]], dtype=float32) 

Чтобы избежать этой проблемы, вы можете скажите np.square использовать тип данных с плавающей точкой:

In [15]: np.sqrt(np.square(a, dtype=np.float64) + np.square(b, dtype=np.float64)) 
Out[15]: 
array([[ 1.  , 254.  , 252.00198412, 255.  , 
     255.  , 255.00196078]]) 

вы можете также использовать функцию numpy.hypot, но вы все равно можете использовать dtype аргумент, в противном случае тип данных по умолчанию np.float16:

In [16]: np.hypot(a, b) 
Out[16]: array([[ 1., 254., 252., 255., 255., 255.]], dtype=float16) 

In [17]: np.hypot(a, b, dtype=np.float64) 
Out[17]: 
array([[ 1.  , 254.  , 252.00198412, 255.  , 
     255.  , 255.00196078]]) 

Вы можете спросить, почему dtype аргумента, который я использовал в numpy.square и numpy.hypot не отображается в строках документации из этой функции. Обе эти функции: numpy "ufuncs", и авторы numpy решили, что лучше показать только основные аргументы в docstring. Необязательные аргументы: documented in the reference manual.

+0

Это сработало! Спасибо за подробное объяснение! Будет ли использовать numpy.hypot более «pythonic», чем то, как я это делаю сейчас? –

0

Для этого простого случая, он отлично работает:

In [1]: a = np.array([[ 0, 2, 4, 6, 8]]) 
In [2]: b = np.array([[ 1, 3, 5, 7, 9]]) 
In [3]: c = np.sqrt(np.square(a) + np.square(b)) 

In [4]: print(c) 
[[ 1.  3.60555128 6.40312424 9.21954446 12.04159458]] 

Вы должны делать что-то неправильно.