malibu
malibu

Reputation: 77

Why doesn't np.square return ouput as expected?

I have a 2 dimensional numpy matrix whose type is numpy.ndarray of uint8. Now when I perform np.square on the array, it does not return the expected result.

Here's an example of the code on the console and its output after I create the numpy array:

arr[0, 0] outputs 203

Now, np.square(203) outputs 41209

But, np.square(arr[0, 0]) outputs 249

This odd behavior was also observed for the np.sqrt method. enter image description here

Upvotes: 0

Views: 304

Answers (2)

hpaulj
hpaulj

Reputation: 231355

np.square like other ufunc can return results with various dtypes. Looks like it 'prefers' to return a matching dtype:

In [109]: np.square(np.array([203], 'uint8'),dtype=int)
Out[109]: array([41209])
In [110]: np.square(np.array([203], 'uint8'),dtype='uint8')
Out[110]: array([249], dtype=uint8)
In [111]: np.square(np.array([203], 'uint8'))
Out[111]: array([249], dtype=uint8)
In [112]: np.square(np.array([203], 'uint8'),dtype='uint8')
Out[112]: array([249], dtype=uint8)
In [113]: np.square(np.array([203], 'uint8'),dtype='uint16')
Out[113]: array([41209], dtype=uint16)
In [114]: np.square(np.array([203], 'uint8'),dtype='int')
Out[114]: array([41209])
In [115]: np.square(np.array([203], 'uint8'),dtype='float')
Out[115]: array([41209.])

https://numpy.org/doc/stable/reference/ufuncs.html#casting-rules

and under signature parameter.

In [118]: np.square.types
Out[118]: 
['b->b',
 'B->B',      # uint8
 'h->h',
 'H->H',
 'i->i',
  ...]

There are more details in handling of casting and dtypes, but the basic point is that if using 'exotic' dtypes like unit8 beware of overflow etc. Even with 'int32' overflow can be problem, but at much larger numbers. A more common problem arise when doing some calculation on integers that results in floats.

A recent SO about dtypes with /= operator.

numpy.array's have bizarre behavior with /= operator?

Many times I've had to ask SO questions - what's the shape, what's the dtype. Those are fundamental properties of a numpy array. Getting those right is 80% of the debugging battle.

Upvotes: 1

user13959036
user13959036

Reputation:

According to numpy.org np.uint8is Unsigned integer (0 to 255)

import numpy as np

arr = np.array([[203, 32, 45, 34], [34,322,780,54]])
arr1 = arr.astype('uint8')
arr2 = arr.astype('uint16')

sq = np.square(203)
sq8 = np.square(arr1[0,0])
sq16 = np.square(arr2[0,0])

sq, sq8, sq16, type(sq), type(sq8), type(sq16)

output:

(41209, 249, 41209, numpy.intc, numpy.uint8, numpy.uint16)

41209 is 249 in uint8:

num = np.array([41209])
num1 = arr.astype('uint8')
num1
>>> array([249], dtype=uint8)

Upvotes: 3

Related Questions