numpyscipynumpy-slicing

Creating a reduced-length resampling of a numpy array


I have a numpy array of a certain length, and want to produce a much shorter array, where each value in the shorter array is aggregated based on a bin of values in the original array. In my specific case, this happens to be an audio signal and the function I'm applying is a max over each bin.

It feels like there must be a function like numpy.interp or scipy.interpolate.interp1d which could make this easier. I swear there must be a simpler/cleaner way to do this with a numpy or scipy built-in.

This is the code I write now:

# assume a is an np.array with len(a) == 510
shorten_length = 50
a_shortened = np.zeros(len(a) // shorten_length)

for i in range(len(a_shortened)):
    slice_end = min(len(a), (i+1) * shorten_length) - 1
    _bin_max = np.max(a[i * shorten_length:slice_end+1])
    a_shortened[i] = _bin_max

Solution

  • As long as you are dropping the last slice (when it's smaller than shorten_length), you can use this approach:

    valid_length = len(a) - len(a) % shorten_length
    a_shortened = a[:valid_length].reshape(-1, shorten_length).max(axis=1)
    

    No array copy is involved during slicing or reshaping.