首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何对保留尖峰的信号进行下采样?

如何对保留尖峰的信号进行下采样?
EN

Stack Overflow用户
提问于 2019-11-29 00:59:42
回答 4查看 1.5K关注 0票数 4

我正在分析一个以200 at采样了6-8秒的信号,最重要的部分是尖峰,最多持续1秒。以地震为例。

我得把信号下采样2倍。我试过了:

代码语言:javascript
运行
复制
from scipy import signal

signal.decimate(mysignal, 2, ftype="fir")
signal.resample_poly(mysignal, 1, 2)

对于这两个函数,我得到了相同的结果:信号被重新采样,但尖峰,正和负的尖峰被减小。

我错误的函数,或者我必须通过一个自定义的FIR滤波器?

EN

回答 4

Stack Overflow用户

发布于 2019-12-13 17:11:22

便笺

如果以信号的频率达到采样频率的极限,下采样总是会损坏信号(Nyquist-Shannon采样定理)。在您的情况下,您的尖峰类似于非常高的频率信号,因此您还需要非常高的采样频率。

(示例:你有3个点,中间的一个点有尖峰。你想把它下采样到2个点。把钉子放在哪里?无处可去,因为你的样本用完了。)

然而,如果你真的想要对信号进行下采样,但你仍然想(或多或少准确地)保留特定点(在你的情况下是尖峰),你可以尝试,这会“保存”你的尖峰,对信号进行下采样,然后才在相应的下采样信号位置应用“保存的”尖峰。

要做的步骤:

1)获得峰值,或者换句话说,局部最大值(或最小值)。

示例:Pandas finding local max and min

2)对信号进行下采样

3)用你从1)得到的尖峰,替换相应的下采样值

(请考虑到您的信号将被损坏。你不能在不丢失由一个或两个点表示的尖峰的情况下进行下采样)

编辑

示例

这是如何保持尖峰的例子。它只是一个示例,因为它现在不适用于负值

代码语言:javascript
运行
复制
import numpy as np
import matplotlib.pyplot as plt
from collections import deque


t = np.arange(1000)/100
y = np.sin(t*2*3.14)
y[150]=5
y[655]=5
y[333]=5
y[250]=5

def downsample(factor,values):
    buffer_ = deque([],maxlen=factor)
    downsampled_values = []
    for i,value in enumerate(values):
        buffer_.appendleft(value)
        if (i-1)%factor==0:
            #Take max value out of buffer
            # or you can take higher value if their difference is too big, otherwise just average
            downsampled_values.append(max(buffer_))
    return np.array(downsampled_values)

plt.plot(downsample(10,y))
plt.show()

票数 4
EN

Stack Overflow用户

发布于 2019-12-09 09:04:21

如果您的硬件支持,您可以以尽可能高的频率采样,但仅在达到最小幅度差或时间差时保存一个点。这样,您的实际数据点将根据任一标准进行过滤。当信号没有真正改变时,你有你想要的采样率,峰值也会记录下来。

让我们假设数据包含您在恒定采样率下的采样点。在此算法结束时,保存的列表将包含数据的所有重要时间戳和sample_point条目

代码语言:javascript
运行
复制
DIVIDER = 5
THRESHOLD = 1000

saved = [ [0, data[0]] ]

for i in range(1, len(data)):
    if( (i % DIVIDER == 0) || (abs(data[i] - data[i - 1]) > THRESHOLD) ):
        saved.append([ i, data[i] ])

与查看两个采样点之间的振幅差异不同,您还可以保存位于某个振幅之上或之下的所有数据点,只需在这段简单的代码中进行微小的更改。

票数 0
EN

Stack Overflow用户

发布于 2019-12-13 17:44:44

如果你对别名不太挑剔,你可以只取每秒(N)样本的最大值。

代码语言:javascript
运行
复制
def take(N, samples):
    it = iter(samples)
    for _ in range(len(samples)/N):
        yield max(it.next() for _ in range(N))

注意到这一点:

代码语言:javascript
运行
复制
import random
random.seed(1)

a = [random.gauss(10,3) for _ in range(100)]

for c in take(5, a):
    print c
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59093503

复制
相关文章

相似问题

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