Downsample 1D numpy массив

у меня есть 1-d массив numpy, который я хотел бы downsample. Любой из следующих методов приемлем, если растр downsampling не идеально подходит для данных:

  • перекрытие интервалов downsample
  • преобразуйте любое количество значений, оставшихся в конце, в отдельное значение
  • интерполировать, чтобы соответствовать растр

в основном, если у меня есть

1 2 6 2 1

и я downsampling в 3 раза, все ниже приведены ok:

3 3

3 1.5

или то, что интерполяция дала бы мне здесь.

Я просто ищу самый быстрый/простой способ сделать это.

нашел scipy.signal.decimate, но это звучит так прореживает значения (вынимает их по мере необходимости и оставляет только один в X). scipy.signal.resample

не могли бы вы мне помочь? Это кажется очень простой задачей, но все эти функции довольно сложны...

2 ответов


в простом случае, когда размер массива делится на коэффициент понижения (R), вы можете reshape Ваш массив и возьмите среднее значение вдоль новой оси:

import numpy as np
a = np.array([1.,2,6,2,1,7])
R = 3
a.reshape(-1, R)
=> array([[ 1.,  2.,  6.],
         [ 2.,  1.,  7.]])

a.reshape(-1, R).mean(axis=1)
=> array([ 3.        ,  3.33333333])

в общем случае вы можете заполнить свой массив с помощью NaNs до размера, кратного R, и принимать с помощью scipy.nanmean.

import math, scipy
b = np.append(a, [ 4 ])
b.shape
=> (7,)
pad_size = math.ceil(float(b.size)/R)*R - b.size
b_padded = np.append(b, np.zeros(pad_size)*np.NaN)
b_padded.shape
=> (9,)
scipy.nanmean(b_padded.reshape(-1,R), axis=1)
=> array([ 3.        ,  3.33333333,  4.])

Если размер массива не делится на коэффициент downsampling (R), изменение (разделение) массива может быть сделано с помощью np.linspace последующим имею в виду каждого подмассива.

input_arr = np.arange(531)

R = 150 (number of split)

split_arr = np.linspace(0, len(input_arr), num=R+1, dtype=int)

dwnsmpl_subarr = np.split(input_arr, split_arr[1:])

dwnsmpl_arr = np.array( list( np.mean(item) for item in dwnsmpl_subarr[:-1] ) )