Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 两个阵列之间的移动均方误差&x27;有效';,它们完全重叠的地方_Python_Numpy_Correlation_Convolution - Fatal编程技术网

Python 两个阵列之间的移动均方误差&x27;有效';,它们完全重叠的地方

Python 两个阵列之间的移动均方误差&x27;有效';,它们完全重叠的地方,python,numpy,correlation,convolution,Python,Numpy,Correlation,Convolution,我有一个嘈杂的方形信号,如下所示: 振幅是已知的。为了匹配完整的正方形,我可以创建一个正方形的模式,并应用np.correlate,找到信号和模式最大重叠的地方。我想应用类似的方法来找到边缘,尝试与以下两种模式相关联: 因为相关性只不过是一个卷积,所以这不起作用。模式的一半等于0,这一半的卷积将返回0,无论信号上的位置如何;而另一半等于-X,振幅为X。当信号振幅最大时,与信号卷积的第二半部分将最大。在信号图上,您可以观察到正方形不是完美的,并且起点的振幅稍大。基本上,这两种相关性都会导致在平

我有一个嘈杂的方形信号,如下所示:

振幅是已知的。为了匹配完整的正方形,我可以创建一个正方形的模式,并应用
np.correlate
,找到信号和模式最大重叠的地方。我想应用类似的方法来找到边缘,尝试与以下两种模式相关联:

因为相关性只不过是一个卷积,所以这不起作用。模式的一半等于
0
,这一半的卷积将返回
0
,无论信号上的位置如何;而另一半等于
-X
,振幅为
X
。当信号振幅最大时,与信号卷积的第二半部分将最大。在信号图上,您可以观察到正方形不是完美的,并且起点的振幅稍大。基本上,这两种相关性都会导致在平方开始处匹配,其中卷积最大。未检测到斜坡上升(正方形的末端)

为了避免这个问题,我想使用不同的操作。因为我知道方形信号的振幅,所以我可以生成一个具有正确振幅的图案,在本例中约为
-0.3
。因此,我想获取模式并将其滑动到信号上。在每一步,我将计算均方误差,我的模式将与均方误差最小的位置处的信号匹配。此外,我希望使用与卷积“valid”相同的设置类型,其中仅当两个数组完全重叠时才执行操作

您知道其他方法吗;和/或我应该使用哪个函数、方法?我找不到一个多功能行
np.convolve
np.correlate


编辑:因为我在库中找不到预先编码的函数,所以我用while循环编码了我的函数。这是相当低效的。。。它在codereview上进行升级。

由于噪声非常小,您可以计算信号随环路发生剧烈变化的位置,例如:

范围内i的
(开始+10,结束):
如果(abs(数据[i-10]-数据[i])>0.1):
foundChange()

我认为用阶跃函数卷积/关联信号仍然非常接近最优解,因为这类似于,可以证明是最优的(在某些条件下,噪声可能需要是高斯噪声)

唯一的问题是模板(step函数)包含DC部件。删除此项将获得所需的结果:

import numpy as np
import matplotlib.pyplot as plt


# simulate the signal
signal = np.zeros(4000)
signal[200:-400] = -0.3
signal += 0.005 * np.random.randn(*signal.shape)

plt.plot(signal)
plt.title('Simulated signal')
plt.show()


# convolve with template with non-zero DC
templ = np.zeros(200)
templ[100:] = 1  # step from 0 to 1
plt.plot(np.convolve(signal, templ))
plt.title('Convolution with template with DC component')
plt.show()

# convolve with template without DC
templ_ac = templ - templ.mean()  # step from -0.5 to +0.5
plt.plot(np.convolve(signal, templ_ac))
plt.title('Convolution with template without DC component')
plt.show()
结果:

理解这一点的方法是,
convalve(signal,template)=convalve(signal,template_DC)+convalve(signal,template_AC)
,其中
template_DC=mean(template)
template_AC=template-template_DC
。第一部分是信号与平面模板的卷积,它只是信号的平滑版本。第二部分是您想要的“边缘检测”信号。如果不减去模板的AC部分,则无趣的第一部分将主导有趣的部分

请注意,模板的缩放并不重要,模板中的步长不必为0.3。这只会导致最终结果中出现比例因子。还请注意,此方法不依赖于步长的精确值,因此信号中较大的步长将对边缘检测产生较大影响


如果知道步长始终精确为0.3,并且希望对不同振幅的步长不敏感,则可以对模板的每一个可能的偏移对信号进行某种最小二乘拟合,并且仅在残差足够小的情况下触发边缘检测。这会很慢,但可能会更好地拒绝振幅错误的步骤。

以最小的重复性分享您的代码尝试example@RahulVishwakarma将数组1的卷积与数组2共享没有意义。这是一行比任何了解这方面的人都要多的代码。我也不愿意手工编写一个完整的函数来执行移动均方误差操作,因为问题的关键是询问是否有人知道有一个库(numpy、scipy等)预先编码了此操作。您可以使用比较来确定信号何时发出changes@RahulVishwakarma我想你指的是“如果信号低于阈值,则方块开始“。不够准确。垂直斜坡不是瞬时的,取决于信号的振幅。。。这就是为什么我正在努力实现比阈值更高级的东西,你必须不完全地选择阈值。这就是为什么,如果你能提供最小的可重复性示例,那么我们可以尝试一些东西,正如评论中所说,阈值解不够精确。如果我用1/10振幅的信号,噪音看起来就不会那么可笑了…+选择阈值是我想要避免的事情,因为它在这里也会导致测量错误。+循环绝对是愚蠢的,有numpy矢量化操作更有效。如果我在1e8处采样信号,我很容易得到300 Mb的数据文件和450万个点。@Mathieu“选择阈值是我想避免的事情…”,自动生成阈值是否可以接受?@Krish取决于您如何生成它。。正如我在文章中所描述的,我刚刚尝试了一个手写的均方误差函数。它的效率不高(目前,实现还没有矢量化…),但正如我所期望的那样,它确实给了我极好的性能result@Mathieu我在考虑将数据与两个百分位数的平均值进行比较,得到一个位数组:
arr=np.array([0,1,0,1,0,1,1,9,8,9,9]);arr>(np.百分位数(arr,10)+np。