在numpy中找到最小跳跃零交叉

Ale*_*xNe 9 python signal-processing numpy

对于数据分析任务,我想在一个numpy数组中找到零交叉,该数组来自先与sobel式内核然后是墨西哥帽内核的卷积。零交叉使我能够检测数据的边缘。

不幸的是,数据有些嘈杂,20在下面的示例中,我只想找到具有最小跳转大小的零交叉点:

import numpy as np
arr = np.array([12, 15, 9, 8, -1, 1, -12, -10, 10])
Run Code Online (Sandbox Code Playgroud)

应该导致

>>>array([1, 3, 7])
Run Code Online (Sandbox Code Playgroud)

要么

>>>array([3, 7])
Run Code Online (Sandbox Code Playgroud)

3的索引在哪里-1,就在第一跳的中间之前,7是的索引-10

我尝试了以下代码的修改(来源:有效地检测python中的符号变化

zero_crossings = np.where(np.diff(np.sign(np.trunc(arr/10))))[0]
Run Code Online (Sandbox Code Playgroud)

正确地忽略了小的跳跃,但是将零交叉点置于 [1,5,7]

什么是有效的方法?

最小跳跃的定义并不严格,但结果应符合我的问题。

编辑:澄清

arr = np.array([12, 15, 9, 8, -1, 1, -12, -10, 10])
arr_floored = np.trunc(arr/10)
>>>>np.array([10, 10, 0, 0, 0, 0, -10, -10, 10])
sgn = np.sign(arr_floored)
>>>>array([ 1,  1,  0,  0,  0,  0, -1, -1,  1])
dsgn = np.diff(sgn)
>>>>array([ 0, -1,  0,  0,  0, -1,  0,  2])
np.where(dsgn)
>>>>(array([1, 5, 7], dtype=int64),)
Run Code Online (Sandbox Code Playgroud)

其他边缘情况:

arr = [10,9,8,7,6,5,4,3,2,1,0,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10]
Run Code Online (Sandbox Code Playgroud)

应该导致

>>> np.array([10])
Run Code Online (Sandbox Code Playgroud)

还只是注意到:问题可能是不适定的(从数学意义上来说)。我将在今天晚些时候澄清它。

Mik*_*ike 3

这是一个解决方案,它给出了涉及噪声阈值的交叉点的中点,以过滤跨多个数据点应用的零附近潜在的多个波动。它为您提供的两个示例提供了正确答案。然而,我做了一些假设:

  • 您没有精确定义要考虑的数据点范围来确定交叉点的中点,但我使用了您的示例代码作为基础 - 它正在检测交叉点,因此ABS(start | end) >= 10我使用了满足此条件的最小范围。
    注意:这不会检测从 +15 到 -6 的转换。
    编辑:实际上它并不总是最小范围,但代码应该足以让您开始并根据需要进行调整。
  • 我认为也可以使用 pandas (跟踪感兴趣的数据点的索引)。如果有必要,你可能可以避免使用熊猫。

import numpy as np import pandas as pd arr = np.array([12, 15, 9, 8, -1, 1, -12, -10, 10]) sgn = pd.Series(np.sign(np.trunc(arr/10))) trailingEdge = sgn[sgn!=0].diff() edgeIndex = np.array(trailingEdge[trailingEdge!=0].index) edgeIndex[:-1] + np.diff(edgeIndex) / 2

给出:

array([3., 7.])

arr = [10,9,8,7,6,5,4,3,2,1,0,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10]

给出:

array([10.])