user7715674
user7715674

Reputation: 79

Rounding in numpy?

I have strange problem with python pandas and numpy.

>>> np.float64(1) * np.float64(85000) * np.float64(7.543709)
641215.26500000001

>>> round( np.float64(1) * np.float64(85000) * np.float64(7.543709), 2 )
641215.26000000001

>>> np.round( np.float64(1) * np.float64(85000) * np.float64(7.543709), 2 )
641215.26000000001

How to round to get correct result 641215.27?

Upvotes: 5

Views: 12641

Answers (2)

user7716955
user7716955

Reputation:

Yes, but you can't use round( float(num), 2 ) when you work with dataframes:

for examle: df.first * df.second * df.third How to round in that case? You can't make float(dt.first)?

This is one solution: df.first.apply(lambda x: round(float(x), 2)) But I think is not fast...

Upvotes: 2

Morgoth
Morgoth

Reputation: 5184

Numpy's round method favours even numbers, have a look at the abridged numpy source code:

def round_(a, decimals=0, out=None):
    return around(a, decimals=decimals, out=out)

def around(a, decimals=0, out=None):
    """
    Evenly round to the given number of decimals.

    Notes
    -----
    For values exactly halfway between rounded decimal values, NumPy
    rounds to the nearest even value. Thus 1.5 and 2.5 round to 2.0,
    -0.5 and 0.5 round to 0.0, etc. Results may also be surprising due
    to the inexact representation of decimal fractions in the IEEE
    floating point standard [1]_ and errors introduced when scaling
    by powers of ten.

    Examples
    --------
    >>> np.around([0.37, 1.64])
    array([ 0.,  2.])
    >>> np.around([0.37, 1.64], decimals=1)
    array([ 0.4,  1.6])
    >>> np.around([.5, 1.5, 2.5, 3.5, 4.5]) # rounds to nearest even value
    array([ 0.,  2.,  2.,  4.,  4.])
    >>> np.around([1,2,3,11], decimals=1) # ndarray of ints is returned
    array([ 1,  2,  3, 11])
    >>> np.around([1,2,3,11], decimals=-1)
    array([ 0,  0,  0, 10])

    """

Example:

If you need to print the string you can format it to give you the right answer:

import numpy as np

num = np.float64(1) * np.float64(85000) * np.float64(7.543709)
print(num)
print(float("{0:.2f}".format(num)))
print(np.round(num, 2))
print()

num += 0.02
print(num)
print(float("{0:.2f}".format(num)))
print(np.round(num, 2))

gives you

641215.265
641215.27
641215.26

641215.285
641215.29
641215.28

Upvotes: 10

Related Questions