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]