Approach by creating all such combinations and summing : Here's a vectorized approach using itertools.product
and array-indexing
-
from itertools import product
a = np.asarray(arr) # Convert to array for ease of use and indexing
m,n = a.shape
combs = np.array(list(product(range(n), repeat=m)))
out = a[np.arange(m)[:,None],combs.T].sum(0)
Sample run -
In [296]: arr = [[1, 2, 4], [10, 3, 8], [16, 12, 13], [14, 4, 20]]
In [297]: a = np.asarray(arr)
...: m,n = a.shape
...: combs = np.array(list(product(range(n), repeat=m)))
...: out = a[np.arange(m)[:,None],combs.T].sum(0)
...:
In [298]: out
Out[298]:
array([41, 31, 47, 37, 27, 43, 38, 28, 44, 34, 24, 40, 30, 20, 36, 31, 21,
37, 39, 29, 45, 35, 25, 41, 36, 26, 42, 42, 32, 48, 38, 28, 44, 39,
29, 45, 35, 25, 41, 31, 21, 37, 32, 22, 38, 40, 30, 46, 36, 26, 42,
37, 27, 43, 44, 34, 50, 40, 30, 46, 41, 31, 47, 37, 27, 43, 33, 23,
39, 34, 24, 40, 42, 32, 48, 38, 28, 44, 39, 29, 45])
Memory-efficient approach : Here's an approach without creating all those combinations and instead using on-the-fly broadcasted
summations and the philosophy is very much inspired by this other post
-
a = np.asarray(arr)
m,n = a.shape
out = a[0]
for i in range(1,m):
out = out[...,None] + a[i]
out.shape = out.size # Flatten