Home > front end >  Smart rounding an array in Python
Smart rounding an array in Python

Time:03-08

I'd like to make a function that rounds integers or floats homogeneously and smart. For example, if I have an array like:

[0.672, 0.678, 0.672]

my output would be:

[0.67, 0.68, 0.67]

but also if I have this kind of input:

[17836.982, 160293.673, 103974.287]

my output would be:

[17836, 160293, 103974]

But at the same time, if my array only has close together values such as:

[17836.987, 17836.976, 17836.953]

The output would be:

[17836.99, 17836.98, 17836.95]

CodePudding user response:

An automated way could be to compute all absolute differences, getting the min and finding out the number of decimal places to keep to maintain a representative difference.

This doesn't give the exact output you want but follows the general logic.

Here using numpy to help on the computation, the algorithm is O(n**2):

def auto_round(l, round_int_part=False):
    import numpy as np
    a = np.array(l)
    b = abs(a-a[:,None])
    np.fill_diagonal(b, float('inf'))
    n = int(np.ceil(-np.log10(b.min())))
    # print(f'rounding to {n} decimals') # uncomment to get info
    if n<0:
        if not round_int_part:
            return a.astype(int).tolist()
        return np.round(a, decimals=n).astype(int).tolist()
    return np.round(a, decimals=n).tolist()

auto_round([17836.987, 17836.976, 17836.953])
# [17836.99, 17836.98, 17836.95]

auto_round([0.6726, 0.6785, 0.6723])
# [0.6726, 0.6785, 0.6723]

auto_round([17836.982, 160293.673, 103974.287])
# [ 17836, 160293, 103974]

auto_round([17836.982, 160293.673, 103974.287], round_int_part=True)
# [20000, 160000, 100000]
  • Related