【问题标题】:Filter an array based on density根据密度过滤数组
【发布时间】:2012-11-27 13:21:52
【问题描述】:

我有一个像下面这样的示例图..,我用数组 X 中的一组 (x,y) 值绘制它。

http://bubblebird.com/images/t.png

如您所见,图像在 4000 到 5100 之间有密集的峰值

我的确切问题是我能否以编程方式找到图形最密集的这个范围?
即.. 使用 Array X 如何找到该图密集的范围?
对于这个数组,它将是 4000 - 5100。

为简单起见,假设阵列只有一个密集区域。
如果您能提出一个伪代码/代码,将不胜感激。

【问题讨论】:

  • 您是否尝试过寻找最大的Y 差异,而X 进步最小?虽然我必须承认,这看起来像是某种家庭作业......
  • 只有我一个人看不到图片吗?
  • @Neowizard:我觉得很好......
  • @Dainis:但正如您在 x=300 周围的图表中看到的那样,y 值突然跳跃,x 前进最少......但它是一个薄区域。
  • @everlasto 好吧...然后在更长的X 期间计算它。意义。找到突然爆发的点并总结它们直到你得到x = 500左右。

标签: php python arrays algorithm filter


【解决方案1】:

您可以在移动窗口上使用信号的方差。 这是一个示例(参见附图,其中测试信号为红色,窗口方差为绿色,过滤后的信号为蓝色):

测试信号生成:

import numpy as np
X = np.arange(200) - 100.  
Y = (np.exp(-(X/10)**2) + np.exp(-((np.abs(X)-50.)/2)**2)/3.) * np.cos(X * 10.)

计算移动窗口方差:

window_length = 30 # number of point for the window
variance = np.array([np.var(Y[i-window_length / 2.: i+window_length/2.]) for i in range(200)])

获取方差高的索引(这里我选择的标准方差优于最大方差的一半...您可以根据自己的情况进行调整):

idx = np.where(variance > 0.5 * np.max(variance))

X_min = np.min(X[idx])
# -14.0
X_max = np.max(X[idx])
# 15.0

或过滤信号(将方差低的点设置为零)

Y_modified = np.where(variance > 0.5 * np.max(variance), Y, 0)

【讨论】:

  • 效果很好。我尝试将variance = np.array([np.var(Y[i-window_length / 2.: i+window_length/2.]) for i in range(200)]) 更改为variance = np.array([np.var(Y[i-window_length : i+window_length/2.]) for i in range(200)]) 并且输出仍然很精细。
  • 这意味着你改变了你的窗口长度(现在你的实际长度将是 3./2.*window_length 而不仅仅是 window_length)但是你决定有一个不居中的窗口......为什么?如果您绘制方差,它将向左移动
  • 算了吧..顺便说一句,在我的图表中,请注意 x=1000 之前有两个突然的冲动会影响方差不是吗??.. 所以不是得到 X_min大约 4000,我会更早地得到 X_min。 X_max 无论如何都很好。但是当我对数组进行切片以使其以 X=2000 开头时,我会根据需要得到 X_min。 .. ..??
  • 那些冲动的东西是,即使它们很强大,它们也非常本地化。因此,如果您的窗口足够长,它应该可以正常工作,因为方差是到平均值的距离的平均值,这意味着如果您有一个窗口,其中您的值一直为 0,除了一个点的强值(让说 10.) 平均值几乎为 0,那么距离向量(由值组成的向量 - 平均值)将为零,除了 10 在某一点......所以该距离向量的平均值(实际方差)将几乎是 0!
  • 这就是为什么这种加窗方差方法实际上是在测试峰的密度!不仅是他们的实力!一个真正本地化的强峰将被过滤,而许多峰即使不是那么强也会被保留!我不确定我的解释是否很清楚......如果你不明白,请告诉我!
【解决方案2】:

您可以计算相邻值之间的绝对差值,然后用滑动窗口稍微平滑一下,然后找到平滑后的绝对差值在最大值的 50% 处的区域。

使用python(标签中有python)如下所示:

a = ( 10, 11, 9, 10, 18, 5, 20, 6, 15, 10, 9, 11 )

diffs = [abs(i[0]-i[1]) for i in zip(a,a[1:])]
# [1, 2, 1, 8, 13, 15, 14, 9, 5, 1, 2]
maximum = max(diffs)
# 15
result = [i>maximum/2 for i in diffs]
# [False, False, False, True, True, True, True, True, False, False, False]

【讨论】:

  • 是的..我尝试得到如下图..黄色区域表示“真实”...现在我可以轻松找到我的方式..谢谢@lenik! [bubblebird.com/images/k.png
【解决方案3】:

您可以使用分类算法(例如 k-means),将数据分成簇并找到权重最大的簇

【讨论】:

    猜你喜欢
    • 2021-12-25
    • 2022-01-01
    • 1970-01-01
    • 2021-08-19
    • 2015-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多