8

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?

3 Answers 3

8

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).

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you, slicing works nice for "2" case, but would it still be as nice for a general solution?
How would you generalize this? You can do np.sum([a[:,i::n] for i in xrange(n)], 0) if you might need to sum n consecutive columns, for example.
Your solution is shorter and easier to read, but I timed it and my initial solutions is considerably faster.
@Akavall: the code in my answer is faster than your sum_chunks specifically for n=2. For larger n, other solutions may be faster. My comment solution is an example of a solution, but I was not aiming to optimize.
7

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]])

Comments

1

Here's one way:

>>> a[:,::2] + a[:,1::2]
array([[ 3,  7, 11],
       [15, 19, 23],
       [ 8, 13, 17]])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.