najuste
najuste

Reputation: 234

Rounding numpy float array read from img with python, values returned not rounded

Simple rounding of a floating point numpy array seems not working for some reason..

I get numpy array from reading a huge img (shape of (7352, 7472)). Ex values:

>>> imarray[3500:3503, 5000:5003]
array([[ 73.33999634,  73.40000153,  73.45999908],
       [ 73.30999756,  73.37999725,  73.43000031],
       [ 73.30000305,  73.36000061,  73.41000366]], dtype=float32)

And for rounding I've been just trying to use numpy.around() for the raw value, also writing values to a new array, a copie of raw array, but for some reason no results..

arr=imarray
numpy.around(imarray, decimals=3, out=arr)
arr[3500,5000] #results in 73.3399963379, as well as accessing imarray

So, even higher precision!!! Is that because of such big array?

I need to round it to get the most frequent value (mode), and I'm searching the vay to avoid more and more libraries..

Upvotes: 2

Views: 1904

Answers (2)

unutbu
unutbu

Reputation: 880717

Your array has dtype float32. That is a 4-byte float. The closest float to 73.340 representable using float32 is roughly 73.33999634:

In [62]: x = np.array([73.33999634, 73.340], dtype = np.float32)

In [63]: x
Out[63]: array([ 73.33999634,  73.33999634], dtype=float32)

So I think np.around is rounding correctly, it is just that your dtype has too large a granularity to round to the number you might be expecting.

In [60]: y = np.around(x, decimals = 3)

In [61]: y
Out[61]: array([ 73.33999634,  73.33999634], dtype=float32)

Whereas, if the dtype were np.float64:

In [64]: x = np.array([73.33999634, 73.340], dtype = np.float64)

In [65]: y = np.around(x, decimals = 3)

In [66]: y
Out[66]: array([ 73.34,  73.34])

Note that even though printed representation for y shows 73.34, it is not necessarily true that the real number 73.34 is exactly representable as a float64 either. The float64 representation is probably just so close to 73.34 that NumPy chooses to print it as 73.34.

Upvotes: 4

mgilson
mgilson

Reputation: 310187

The answer by @unutbu is absolutely correct. Numpy is rounding it as close to the number as it can given the precision that you requested. The only thing that I have to add is that you can use numpy.set_printoptions to change how the array is displayed:

>>> import numpy as np
>>> x = np.array([73.33999634, 73.340], dtype = np.float32)
>>> y = np.round(x, decimals = 3)
>>> y
array([ 73.33999634,  73.33999634], dtype=float32)
>>> np.set_printoptions(precision=3)
>>> y
array([ 73.34,  73.34], dtype=float32)

Upvotes: 2

Related Questions