首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对一维numpy数组进行下采样

对一维numpy数组进行下采样
EN

Stack Overflow用户
提问于 2013-12-02 14:24:58
回答 3查看 31.2K关注 0票数 23

我有一个一维numpy数组,我想对其进行下采样。如果下采样光栅与数据不完全匹配,则可以使用以下任一方法:

对于单独的下采样value

  • interpolate,无论在末尾保留多少个值,
  • 重叠下采样都可以拟合栅格

基本上,如果我有

代码语言:javascript
运行
复制
1 2 6 2 1

我向下采样了3倍,下面所有的都是可以的:

代码语言:javascript
运行
复制
3 3

3 1.5

或者任何插值法能给我的结果。

我只是在寻找最快/最简单的方法来做这件事。

我找到了scipy.signal.decimate,但这听起来像是对值进行了抽取(根据需要去掉它们,只在X中留下一个)。scipy.signal.resample似乎有正确的名称,但我不明白他们在描述中的整个傅里叶事情要去哪里。我的信号不是特别周期性的。

你能帮我一下吗?这似乎是一项非常简单的任务,但所有这些功能都相当复杂……

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-12-02 14:57:50

在数组大小可被下采样因子(R)整除的简单情况下,您可以reshape您的数组,并沿着新轴取平均值:

代码语言:javascript
运行
复制
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填充数组,使其大小可被R整除,然后使用scipy.nanmean取平均值。

代码语言:javascript
运行
复制
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.])
票数 30
EN

Stack Overflow用户

发布于 2019-06-08 06:20:25

这里有几种使用线性插值或傅立叶方法的方法。这些方法支持上采样和下采样。

代码语言:javascript
运行
复制
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import resample
from scipy.interpolate import interp1d

def ResampleLinear1D(original, targetLen):
    original = np.array(original, dtype=np.float)
    index_arr = np.linspace(0, len(original)-1, num=targetLen, dtype=np.float)
    index_floor = np.array(index_arr, dtype=np.int) #Round down
    index_ceil = index_floor + 1
    index_rem = index_arr - index_floor #Remain

    val1 = original[index_floor]
    val2 = original[index_ceil % len(original)]
    interp = val1 * (1.0-index_rem) + val2 * index_rem
    assert(len(interp) == targetLen)
    return interp

if __name__=="__main__":

    original = np.sin(np.arange(256)/10.0)
    targetLen = 100

    # Method 1: Use scipy interp1d (linear interpolation)
    # This is the simplest conceptually as it just uses linear interpolation. Scipy
    # also offers a range of other interpolation methods.
    f = interp1d(np.arange(256), original, 'linear')
    plt.plot(np.apply_along_axis(f, 0, np.linspace(0, 255, num=targetLen)))

    # Method 2: Use numpy to do linear interpolation
    # If you don't have scipy, you can do it in numpy with the above function
    plt.plot(ResampleLinear1D(original, targetLen))

    # Method 3: Use scipy's resample
    # Converts the signal to frequency space (Fourier method), then back. This
    # works efficiently on periodic functions but poorly on non-periodic functions.
    plt.plot(resample(original, targetLen))

    plt.show()
票数 2
EN

Stack Overflow用户

发布于 2017-12-22 02:12:53

如果阵列大小不能被下采样因子(R)整除,则阵列的整形(分裂)可以使用紧跟着每个子阵的均值的np.linspace来完成。

代码语言:javascript
运行
复制
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] ) )
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20322079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档