简体   繁体   中英

How to perform non-integer average pooling one a 1d numpy array?

Suppose I have a 1d Numpy array with size n. How can I perform average pooling to resize the array to size m, where the factor R=n/m is non-integer. This would be equivalent to partitioning the array in non-integer bins and calculating the average on each bin. The code snippet shows the functionality I am looking for, it calculates the average on each bin and also takes array elements which are only fractionally in the bin into account.

result = []

bins = np.linspace(0, len(array), m+1)
for i, j in zip(bins[:-1], bins[1:]):
    i_ceil = int(np.ceil(i))
    i_diff = i_ceil - i

    j_floor = int(np.floor(j))
    j_diff = j - j_floor

    numerator = np.sum(array[i_ceil:j_floor]) + array[max(0, i_ceil-1)] * i_diff + array[min(len(array)-1, j_floor)] * j_diff

    result.append(numerator / (j-i))

assert np.mean(np.array(result)) == np.mean(array)
return np.array(result)

Two approaches:

  1. to split [0, 1 .. n-1] into exactly m non-overlapping pieces, see Bresenham's_line_algorithm : m horizontal line segments make a balanced split, see the picture. This is probably overkill.

  2. smooth the n data points, resample at m . For example with n = 101, m = 10 , filter all the data with np.convolve or scipy.signal.lfilter or filtfilt ... then take yfiltered[[5, 15 .. 95]] . (There's a huge literature on resampling / compressing audio and video signals, over 800 dsp.stack questions/tagged/compression .)

Bytheway np.split is nice.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM