views:

72

answers:

3

I would like to take bites out of a list (or array) of a certain size, return the average for that bite, and then move on to the next bite and do that all over again. Is there some way to do this without writing a for loop?

In [1]: import numpy as np
In [2]: x = range(10)
In [3]: np.average(x[:4])
Out[3]: 1.5
In [4]: np.average(x[4:8])
Out[4]: 5.5
In [5]: np.average(x[8:])
Out[5]: 8.5

I'm looking for something like, np.average(x[:bitesize=4]) to return: [1.5,5.5,8.5].

I have looked at slicing arrays and stepping through arrays, but I haven't found anything that does something like I want to have happen.

+1  A: 

The grouper itertools recipe can help.

Ignacio Vazquez-Abrams
+5  A: 
[np.average(x[i:i+4]) for i in xrange(0, len(x), 4) ]
GregS
+1  A: 

Using numpy, you can use np.average with the axis keyword:

import numpy as np
x=np.arange(12)
y=x.reshape(3,4)
print(y)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]
print(np.average(y,axis=1))
# [ 1.5  5.5  9.5]

Note that to reshape x, I had to make x start with a length evenly divisible by the group size (in this case 4).

If the length of x is not evenly divisible by the group size, then could create a masked array and use np.ma.average to compute the appropriate average.

For example,

x=np.ma.arange(12)
y=x.reshape(3,4)
mask=(x>=10)
y.mask=mask
print(y)
# [[0 1 2 3]
#  [4 5 6 7]
#  [8 9 -- --]]
print(np.ma.average(y,axis=1))
# [1.5 5.5 8.5]
unutbu
This actually answers a latent mask array question that I've had but haven't asked...
JBWhitmore