While answering this question, I was wondering what is the most efficient/simple way to distribute a predefined value across the 1 values of a binary array. The value should be distributed as fairly as possible (the remainder is distributed randomly so that each cell can eventually get one extra).
For instance, distributing 4
in [1, 0, 1]
would result in [2, 0, 2]
, while distributing 5
could give either [3, 0, 2]
or [2, 0, 3]
. The distribution should work on an array of arbitrary dimensions.
Let's call distribute
the function. It should take as parameters value
the value to be distributed and array
the binary array and return an array of same shape with the distributed value.
def distribute(value, array):
...
return # array of same shape with fairly distributed value
>>> distribute(10, np.array([0,1]))
array([ 0, 10])
>>> distribute(10, np.array([1,0,1]))
array([5, 0, 5])
>>> distribute(9, np.array([1,0,1]))
array([4, 0, 5]) # could also be array([5, 0, 4])
>>> distribute(9, np.array([[1,0],[0,1]]))
array([[5, 0],
[0, 4]])
>>> distribute(10, np.diag(np.ones(4)).reshape(2,2,-1))
array([[[3., 0., 0., 0.],
[0., 2., 0., 0.]],
[[0., 0., 3., 0.],
[0., 0., 0., 2.]]])
See my proposed solution in the answers. Please propose alternative approaches, the goal is to find the most efficient and/or simple.