python - Proportional rounding error -
i have snippet of code takes big info set , turns proportional smaller info set allow me explain:
lets have 20 bluish marbles , 10 reddish marbles, if wanted represent info 3 marbles utilize 2 bluish , 1 reddish marble.
i don't mind if not exact illustration representing 17 bluish , 16 reddish 4 marbles. closest way proportionally represent 2 bluish , 2 reddish , that's okay
this code in python :
from random import randrange data_set = [randrange(100, 1000) x in range(5)] required_amount = 20 special_number = required_amount / sum(data_set) proportional_data_set = [round(x * special_number) x in data_set] print(data_set) print(required_amount) print(proportional_data_set) print(sum(proportional_data_set))
the problem required sample 20 proportional info set give me 21 or 19 total. i'm assuming it's because of rounding error know improve way solve problem?
a sample output working correctly :
[832, 325, 415, 385, 745] 20 [6, 2, 3, 3, 6] 20
a sample working incorrectly :
[414, 918, 860, 978, 438] 20 [2, 5, 5, 5, 2] 19
if knows of similar methods great.
here's 1 way solve problem. calculate special_number
number of units in data_set
per "marble". utilize divmod() calculate both proportional amount , remainder. since divmod() returns integer quotient, sum(proportional_data_set)
less required_amount
in cases.
finally, utilize loop find highest remainder , increment proportional_data_set until sum(proportional_data_set) = required_amount
.
from random import randrange data_set = [randrange(100, 1000) x in range(5)] required_amount = 20 special_number = sum(data_set) // required_amount print("data set:") print(data_set) print("special number:") print(special_number) # divmod() returns pair of numbers, split them quotients , remainders pairs = [divmod(x, special_number) x in data_set] proportional_data_set = [x[0] x in pairs] remainder = [x[1] x in pairs] print print("proportional info set before adjusting:") print(proportional_data_set), "=", sum(proportional_data_set) print("remainders:") print(remainder) while sum(proportional_data_set) < required_amount: = remainder.index(max(remainder)) # index of highest remainder proportional_data_set[i] += 1 # add together marble index remainder[i] = -1 # don't utilize remainder 1 time again print print("proportional info set after adjusting:") print(proportional_data_set), "=", sum(proportional_data_set) print("remainders:") print(remainder)
the output looks like:
data set: [546, 895, 257, 226, 975] special number: 144 proportional info set before adjusting: [3, 6, 1, 1, 6] = 17 remainders: [114, 31, 113, 82, 111] proportional info set after adjusting: [4, 6, 2, 1, 7] = 20 remainders: [-1, 31, -1, 82, -1]
the highest remainders used increment proportional info set , set -1.
python dataset rounding
No comments:
Post a Comment