Reputation: 86306
Let's say I have the following array:
a = np.array([[1,2,3,4,5,6],
[7,8,9,10,11,12],
[3,5,6,7,8,9]])
I want to sum the first two values of the first row: 1+2 = 3
, then next two values: 3+4 = 7
, and then 5+6 = 11
, and so on for every row. My desired output is this:
array([[ 3, 7, 11],
[15, 19, 23],
[ 8, 13, 17]])
I have the following solution:
def sum_chunks(x, chunk_size):
rows, cols = x.shape
x = x.reshape(x.size / chunk_size, chunk_size)
return x.sum(axis=1).reshape(rows, cols/chunk_size)
But it feels unnecessarily complicated, is there a better way? Perhaps a built-in?
Upvotes: 8
Views: 9185
Reputation: 67497
When I have to do this kind of stuff, I prefer reshaping the 2D array into a 3D array, then collapse the extra dimension with np.sum
. Generalizing it to n-dimensional arrays, you could do something like this:
def sum_chunk(x, chunk_size, axis=-1):
shape = x.shape
if axis < 0:
axis += x.ndim
shape = shape[:axis] + (-1, chunk_size) + shape[axis+1:]
x = x.reshape(shape)
return x.sum(axis=axis+1)
>>> a = np.arange(24).reshape(4, 6)
>>> a
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
>>> sum_chunk(a, 2)
array([[ 1, 5, 9],
[13, 17, 21],
[25, 29, 33],
[37, 41, 45]])
>>> sum_chunk(a, 2, axis=0)
array([[ 6, 8, 10, 12, 14, 16],
[30, 32, 34, 36, 38, 40]])
Upvotes: 7
Reputation: 179697
Just use slicing:
a[:,::2] + a[:,1::2]
This takes the array formed by every even-indexed column (::2
), and adds it to the array formed by every odd-indexed column (1::2
).
Upvotes: 8
Reputation: 151147
Here's one way:
>>> a[:,::2] + a[:,1::2]
array([[ 3, 7, 11],
[15, 19, 23],
[ 8, 13, 17]])
Upvotes: 1