确定数据集的“波动性” - Python

13 投票
2 回答
1032 浏览
提问于 2025-04-16 07:08

我正在开发一款软件,需要处理一组数据的“波动性”。下面是我会收到的输入样本,并且合并了每个垂直像素条的亮度图:

alt text

从图中可以很明显看出,左边的边缘是非常“波动”的(也就是说,有很多的波谷和波峰),我想要生成这幅图像的一组关键点。我对数据应用了大约10次高斯平滑函数,但一开始的数据看起来还是很“波动”。

有没有什么好的建议呢?

这是我最初的代码,但结果并不是很好(在处理波动性方面):

def local_maximum(list, center, delta):
  maximum = [0, 0]

  for i in range(delta):
    if list[center + i] > maximum[1]: maximum = [center + i, list[center + i]]
    if list[center - i] > maximum[1]: maximum = [center - i, list[center - i]]

  return maximum

def count_maxima(list, start, end, delta, threshold = 10):
      count = 0

  for i in range(start + delta, end - delta):
    if abs(list[i] - local_maximum(list, i, delta)[1]) < threshold: count += 1

  return count

def wiggliness(list, start, end, delta, threshold = 10):
  return float(abs(start - end) * delta) / float(count_maxima(list, start, end, delta, threshold))

2 个回答

1

对于这种情况,numpy可以让事情变得简单很多,因为它提供了一些很有用的函数,可以用来处理向量数据,比如给每个元素加一个数,计算平均值等等。

举个例子,你可以尝试计算原始数据的零交叉率(wiggliness1)或者一阶差分数据的零交叉率(wiggliness2),具体用哪个要看“wiggliness”到底指的是什么。如果你想忽略全局趋势,可能更适合使用差分数据。对于x,你可以从原始数据中选择一个感兴趣的片段,这样就能得到一个局部的wiggliness度量。

如果你使用原始数据,在去掉偏差后,可能还想把所有小于某个阈值的值设为0,这样就可以忽略那些幅度很小的波动。

import numpy as np

def wiggliness1(x):
    #remove bias:
    x=x-np.average(x)
    #calculate zero crossing rate:
    np.sum(np.abs(np.sign(np.diff(x))))


def wiggliness(x):
    #calculate zero crossing rate of the first difference:
    return np.sum(np.abs(np.sign(np.diff(np.sign(np.diff(x))))))
5

可以看看低通滤波器、高通滤波器、陷波滤波器和带通滤波器,还有傅里叶变换或者小波变换。这些都是用来分析信号在不同时间段内的频率成分的不同方法。

如果我们能搞清楚什么是“波动性”,那就更好了。我觉得最左边的边缘是波动的,因为它包含了更多的高频成分,你可以通过傅里叶变换来可视化这一点。

如果你对那个红色信号使用高通滤波器,你就能得到仅仅是高频成分,然后你可以测量这些成分的幅度,并设定阈值来判断波动性。不过,我想“波动性”这个概念可能需要更正式的定义。

撰写回答