Reputation: 43
I need from an array (or scalar) all possible combinations.
I have an Array np.array([0, 1, 0, 1])
or a scalar np.sum(np.array([0, 1, 0, 1]))
. Now i need all combinations such as:
[[2,0,0,0],
[1,1,0,0],
[1,0,1,0],
…
[0,0,1,1],
[0,0,0,2]]
The sum from an elements of all possible combinations can not exceed the sum of the scalar. I know the solution from "Using numpy to build an array of all combinations of two arrays“. But it does not help me for this problem. Have somebody any idea?
Upvotes: 1
Views: 3775
Reputation: 120391
Several years later, maybe it could help someone.
The strategy is to generate all the combinations using itertools.product
and keep right rows with numpy.where
(which is faster).
import numpy as np
import itertools
a = np.array([0, 1, 0, 1])
l = len(a)
s = sum(a)
m = np.array(list(itertools.product(range(0, s+1), repeat=l)))
m = m[np.where(np.sum(m, axis=1) <= s)]
>>> m
array([[0, 0, 0, 0],
[0, 0, 0, 1],
[0, 0, 0, 2],
[0, 0, 1, 0],
[0, 0, 1, 1],
[0, 0, 2, 0],
[0, 1, 0, 0],
[0, 1, 0, 1],
[0, 1, 1, 0],
[0, 2, 0, 0],
[1, 0, 0, 0],
[1, 0, 0, 1],
[1, 0, 1, 0],
[1, 1, 0, 0],
[2, 0, 0, 0]])
Upvotes: 0
Reputation: 949
Here is a very simple (and inefficient) way of doing what you want for the scalar case. For the array case just get the numbers n and m from the sum and length of the array. I'm sure its possible to do significantly better than this with some additional thinking but unless your numbers get significantly larger then this will suffice:
import itertools
import numpy as np
n=2 #number of elements to distribute
m=4 #length of arrays to distribute in
arrays = []
for combination in itertools.combinations_with_replacement(range(m), n):
arrays.append(np.zeros(m,dtype=int))
for index in combination:
arrays[-1][index] += 1
for array in arrays:
print(array)
Output:
[2 0 0 0]
[1 1 0 0]
[1 0 1 0]
[1 0 0 1]
[0 2 0 0]
[0 1 1 0]
[0 1 0 1]
[0 0 2 0]
[0 0 1 1]
[0 0 0 2]
Upvotes: 3