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])
в общем случае вы можете заполнить свой массив с помощью NaN
s до размера, кратного 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] ) )