Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split an integer into bins

Given a single integer and the number of bins, how to split the integer into as equal parts as possible?

E.g. the sum of the outputs should be equals to the input integer

[in]: x = 20 , num_bins = 3
[out]: (7, 7, 6)

Another e.g.

[in]: x = 20 , num_bins = 6
[out]: (4, 4, 3, 3, 3, 3)

I've tried this:

x = 20
num_bins = 3
y = [int(x/num_bins)] * num_bins
for i in range(x%num_bins):
    y[i] += 1

It works but there must be a simpler/better way, maybe using bisect or numpy?

Using numpy from https://stackoverflow.com/a/48899071/610569 , I could do this too:

list(map(len, np.array_split(range(x), num_bins)))

But that's a little convoluted with creating a generate to get the a pretend list and getting the length.

like image 202
alvas Avatar asked Feb 22 '18 02:02

alvas


1 Answers

The built-in divmod function could be useful for this.

def near_split(x, num_bins):
    quotient, remainder = divmod(x, num_bins)
    return [quotient + 1] * remainder + [quotient] * (num_bins - remainder)

Demo

In [11]: near_split(20, 3)
Out[11]: [7, 7, 6]
In [12]: near_split(20, 6)
Out[12]: [4, 4, 3, 3, 3, 3]
like image 90
miradulo Avatar answered Sep 29 '22 13:09

miradulo