对于数据分析任务,我想在一个numpy数组中找到零交叉点,该数组来自于先是类似于sobel的内核,然后是墨西哥帽内核的卷积。零交叉使我能够检测数据的边缘。
不幸的是,数据有些嘈杂,我只想找到具有最小跳转大小的零交叉点,在下面的示例中为{
"command": "multiCommand.gotoDebuggerExecutionPoint",
"sequence": [
"workbench.debug.action.focusCallStackView",
"list.clear",
"list.focusFirst",
"list.select"
]
}
:
20
应该导致
import numpy as np
arr = np.array([12, 15, 9, 8, -1, 1, -12, -10, 10])
或
>>>array([1, 3, 7])
>>>array([3, 7])
是3
的索引,刚好在第一跳的中间,而-1
是7
的索引
我尝试修改以下代码(来源:Efficiently detect sign-changes in python)
-10
可以正确忽略小跳,但将零交叉点放在zero_crossings = np.where(np.diff(np.sign(np.trunc(arr/10))))[0]
什么是有效的方法?
最小跳跃的定义并不严格,但是结果应该符合我的问题。
编辑:为澄清起见
[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),)
应该导致
arr = [10,9,8,7,6,5,4,3,2,1,0,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10]
也刚刚注意到:问题可能是不适定的(从数学意义上来说)。我将在今天晚些时候进行澄清。
答案 0 :(得分:2)
这是一个解决方案,它给出了包含噪声阈值的交叉点的中点,以过滤在多个数据点上施加的零附近的潜在多个波动。它为您提供的两个示例给出了正确的答案。 但是,我做了两个假设:
ABS(start | end) >= 10
处的交叉点,因此使用了满足此条件的最小范围。
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.])
答案 1 :(得分:1)
我想你想要
import numpy as np
x = np.array([10, -50, -30, 50, 10, 3, -200, -12, 123])
indices = np.where(np.logical_and(np.abs(np.diff(x)) >= 20, np.diff(np.sign(x)) != 0))[0]
读取为:索引,其中((x的绝对差)大于或等于20)和(符号翻转)
返回
array([0, 2, 5, 7])
通常的numpy函数不能解决这种情况。我建议通过pad函数在末尾添加第一个元素:
import numpy as np
x = np.array([10, 5, 0, -5, -10])
x = np.pad(x, (0, 1), 'wrap')
indices = np.where(np.logical_and(np.abs(np.diff(x)) >= 20, np.diff(np.sign(x)) != 0))[0]