填充其中一个输入时为何python scipy互相关不起作用

填充其中一个输入时为何python scipy互相关不起作用,python,numpy,scipy,cross-correlation,Python,Numpy,Scipy,Cross Correlation,scipy互相关函数根本不适用于特定的一维阵列,我不明白为什么。下面的代码演示了这个问题,只需尝试使用一个跟踪,而不是另一个跟踪 这个问题有点涉及和 !/usr/bin/python3 将numpy作为np导入 从scipy输入信号 将matplotlib.pyplot作为plt导入 def_main: trace=np.数组[0.00000000000000001,0.00000000000000002,0.00000000000000001,0.00000000000000002,0.000

scipy互相关函数根本不适用于特定的一维阵列,我不明白为什么。下面的代码演示了这个问题,只需尝试使用一个跟踪,而不是另一个跟踪

这个问题有点涉及和

!/usr/bin/python3 将numpy作为np导入 从scipy输入信号 将matplotlib.pyplot作为plt导入 def_main: trace=np.数组[0.00000000000000001,0.00000000000000002,0.00000000000000001,0.00000000000000002,0.00000000000000001,0.00000000000000002,0.00000000000000001,0.00000000000000002,向下一步 0.99999999999999998、0.999999999999999999、0.99999999999999999998、0.999999999999999999999、0.999999999999999999、0.999999999999999999、0.999999999999999999999、0.999999999999999999999999、0.999999999999999999999999、0.999999999999999999999999999999、0.999999999999999999999999999999、0.999999999999999999999999999999998,向上移动台阶 0.00000000000000001,0.00000000000000002,0.00000000000000001,0.00000000000000000000002,0.00000000000000001,0.00000000000000000000002,0.00000000000000001,0.00000000000000002,0.00000000000000000000001,0.00000000000000000000002]下台阶 trace=np.数组[0.51231204949426460,0.47472182808002383,0.488060297622723,0.51352464019930,0.585067452537603330,0.62993314829830390,0.57657927012749040,0.55369158834668990,0.562558647226200,0.61576098682569510, 0.62955418648769630, 0.64236215760241170, 0.69063835641941580, 0.75073729780384960, 0.86896478361172370, 0.92216712516515690, 0.91329988783884970, 0.92807831604813670, 0.99113300320800610, 0.99999999999999990, 0.91527040506699960, 0.80098377331469030, 0.71723934679539750, 0.68275634764039450, 0.65812563395824950, 0.63250963159524040, 0.59999708953480900, 0.55172083058422660, 0.54975037348965490, 0.57011178351142090, 0.52807534544936740] 左\u填充\u轨迹=np.padtrace,10,0,mode='constant',constant\u值=trace.min 中心填充轨迹=np.padtrace,5,5,模式=常量,常量值=trace.min 右\u padded\u trace=np.padtrace,0,10,mode='constant',constant\u value=trace.min correlation1=signal.correlatecenter\u padded\u trace,left\u padded\u trace,mode='full',method='fft' correlation2=signal.correlatecenter_padded_trace,center_padded_trace,mode='full',method='fft' correlation3=signal.correlatecenter\u padded\u trace,right\u padded\u trace,mode='full',method='fft' corr_peak_index1=np.argmaxcorrelation1 corr_max1=np.maxcorrelation1 corr_peak_index2=np.argmaxcorrelation2 corr_max2=np.maxcorrelation2 corr_peak_index3=np.argmaxcorrelation3 corr_max3=np.maxcorrelation3 偏移量1=corr_peak_index1-center_padded_trace.size-1 偏移量2=corr_peak_index2-center_padded_trace.size-1 偏移量3=corr_peak_index3-center_padded_trace.size-1 printCorr1:{},Corr2:{},Corr3:{}。格式corr_peak_index1,corr_peak_index2,corr_peak_index3 printOffset1:{},Offset2:{},Offset3:{}。formatoffset1,Offset2,Offset3 plt.图1 plt.311子图 plt.plotrange0,中心填充的跟踪。大小,中心填充的跟踪,“r-”, rangeoffset1,左填充的跟踪。大小+偏移量1,左填充的跟踪,“b-”, range0,correlation1.size,correlation1/corr_max1,'g-', [corr_peak_index1],[1],“k+” plt.subplot312 plt.plotrange0,中心填充的跟踪。大小,中心填充的跟踪,“r-”, rangeoffset2,中心填充的跟踪。大小+偏移量2,中心填充的跟踪,“b-”, range0,correlation2.size,correlation2/corr_max2,'g-', [corr_peak_index2],[1],“k+” plt.subplot313 plt.plotrange0,中心填充的跟踪。大小,中心填充的跟踪,“r-”, rangeoffset3,右填充的跟踪。大小+偏移量3,右填充的跟踪,“b-”, range0,correlation3.size,correlation3/corr_max3,'g-', [corr_peak_index3],[1],“k+” 节目 由于填充添加的移位是相同的,唯一的区别是输入跟踪上的更改,因此从相关性的移位和对齐角度来看,结果应该是相同的,但它们不是

对于第一道合成步骤,相关性和偏移为:1为左填充,2为居中,3为右填充

Corr1:35,Corr2:40,Corr3:45 偏移量1:-5,偏移量2:0,偏移量3:5 对于第二个更自然的痕迹

Corr1:40,Corr2:40,Corr3:40 偏移量1:0,偏移量2:0,偏移量3:0 以下是图表:

在代码中首先绘制合成跟踪

代码中第二个自然轨迹的绘图

解决方案 请参阅下面Paul Panzer的回答和评论

问题在于原始代码使用非零填充

当使用非零值移动阵列时,互相关值会越来越高,峰值会受到影响。以下代码和图像演示了此效果:

trace=np.a 拉雷[0.51231204949426460, 0.47472182808002383, 0.48806029762272723, 0.51352464310119930, 0.58506742537603330, 0.62993314829830390, 0.57657927012749040, 0.55369158834668990, 0.56255864527226200, 0.61576098682569510, 0.62955418648769630, 0.64236215760241170, 0.69063835641941580, 0.75073729780384960, 0.86896478361172370, 0.92216712516515690, 0.91329988783884970, 0.92807831604813670, 0.99113300320800610, 0.99999999999999990, 0.91527040506699960, 0.80098377331469030, 0.71723934679539750, 0.68275634764039450, 0.65812563395824950, 0.63250963159524040, 0.59999708953480900, 0.55172083058422660, 0.54975037348965490, 0.57011178351142090, 0.52807534544936740] 对于np.arange0、trace.min、trace.min/10中的填充_值: 左\u填充的\u轨迹=np.padtrace,10,0,mode='constant',constant\u值=填充的\u值 中心填充轨迹=np.padtrace,5,5,模式=常量,常量值=填充值 相关=信号。相关中心填充跟踪,左填充跟踪,模式='full',方法='fft' corr_peak_index=np.argmaxcorrelation plt.图2 plt.subplot211 plt.标题“左填充轨迹” plt.xticks[] plt.plot左填充轨迹 plt.subplot212 plt.标题“居中填充轨迹” plt.plotcenter\u padded\u trace plt.图3 plt.plotrange0,correlation.size,correlation plt.plot[corr_peak_index],[corr_peak_index],“k+” 节目 结果如下所示。我们可以看到,随着填充值的增加,相关峰值向中心移动

具有不同填充级别的跟踪,从0到最小值

相关值和峰值 使用模式=有效

scipy.signal.correlate(in1, in2, mode='valid', method='auto')
modestr {‘full’, ‘valid’, ‘same’}, optional
指示输出大小的字符串:

满满的 输出是输入的完全离散线性互相关。默认值

有效的 输出仅由不依赖零填充的元素组成。在>“有效”模式下,in1或in2必须至少与每个>维度中的其他元素一样大

同样的 输出与in1大小相同,以“完整”输出为中心


这种差异的原因是,在第二条记录道中,填充的最小值不是零。因此,您不能期望峰值仅随偏移量移动。相反,您得到的是移动的峰值曲线加上一个以最小值缩放的三角形


使用valid没有帮助。事实上,代码在这两种情况下都停止工作。我知道不能使用选项“valid”同步两个跟踪,因为它无法正确推断负移位。只是为了补充前面的注释。根据文档。“valid”模式结果是一个长度为的数组[maxM,N-minM,N+1]。在N和M具有相同大小的情况下,转换为1。简而言之,您只有一个值。对于“相同”:结果长度=maxlengthM,lengthN,您不能将其用于同步,因为当第二条记录道N移动到lef时,您将不会获得小于lengthM的索引相关值,从而转换为对齐不完全是。我在两种情况下都用最小值填充。只是尝试将合成情况下的最小值更改为自然情况下最小值的相同值,结果是相同的。一种情况有效,另一种情况无效。@FábioLobão将最小值变大,你会看到。如果曲线最重要的是,它们是不同的。我有两条记录道,它们的范围从0.47到1左右,点数相同,精度和数字表示形式相同。dtype float64,结果仍然不一致。你试过代码吗?我猜我的平台出了问题。顺便说一句,我使用的是Scipy-版本:1.2.1-Numpy版本:1.16.0-Python系统版本:sys.Version\u infomajor=3,minor=6,micro=8,releaselevel='final',serial=0@F正如我所说,只要实际信号不同,匹配一些任意参数就没有意义。如果这有助于说服你,我在帖子中添加了一个摘要图,显示x-offset作为y偏移的函数,定性行为在y偏移为0时当然是相同的,x偏移被保留,但随着y偏移的增加,x偏移最终将被删除。你是对的,Paul。尽管我无法理解为什么由于填充值增加而导致的相关曲线平滑会影响peak值,该值应始终与移位相关。我猜这是算法的数值限制。我做了一些额外的实验来演示问题的解决方案,并将相应地编辑问题。
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

def _main(offset=0, trace_idx=0):
    trace = [np.array([0.00000000000000001, 0.00000000000000002, 0.00000000000000001, 0.00000000000000002, 0.00000000000000001, 0.00000000000000002, 0.00000000000000001, 0.00000000000000002, 0.00000000000000001, 0.00000000000000002, # down the step
                      0.99999999999999998, 0.99999999999999999, 0.99999999999999998, 0.99999999999999999, 0.99999999999999998, 0.99999999999999999, 0.99999999999999998, 0.99999999999999999, 0.99999999999999998, 0.99999999999999999, 0.99999999999999998, # up the step
                       0.00000000000000001, 0.00000000000000002, 0.00000000000000001, 0.00000000000000002, 0.00000000000000001, 0.00000000000000002, 0.00000000000000001, 0.00000000000000002, 0.00000000000000001, 0.00000000000000002]), # down the step
    np.array([0.51231204949426460, 0.47472182808002383, 0.48806029762272723, 0.51352464310119930, 0.58506742537603330, 0.62993314829830390, 0.57657927012749040, 0.55369158834668990, 0.56255864527226200, 0.61576098682569510,
                      0.62955418648769630, 0.64236215760241170, 0.69063835641941580, 0.75073729780384960, 0.86896478361172370, 0.92216712516515690, 0.91329988783884970, 0.92807831604813670, 0.99113300320800610, 0.99999999999999990, 0.91527040506699960, 
                      0.80098377331469030, 0.71723934679539750, 0.68275634764039450, 0.65812563395824950, 0.63250963159524040, 0.59999708953480900, 0.55172083058422660, 0.54975037348965490, 0.57011178351142090, 0.52807534544936740])][trace_idx]

    trace += offset - trace.min()

    left_padded_trace = np.pad(trace, (10, 0), mode='constant', constant_values=trace.min())
    center_padded_trace = np.pad(trace, (5, 5), mode='constant', constant_values=trace.min())
    right_padded_trace = np.pad(trace, (0, 10), mode='constant', constant_values=trace.min())

    correlation1 = signal.correlate(center_padded_trace, left_padded_trace, mode='full', method='fft')
    correlation2 = signal.correlate(center_padded_trace, center_padded_trace, mode='full', method='fft')
    correlation3 = signal.correlate(center_padded_trace, right_padded_trace, mode='full', method='fft')

    corr_peak_index1 = np.argmax(correlation1)
    corr_max1 = np.max(correlation1)

    corr_peak_index2 = np.argmax(correlation2)
    corr_max2 = np.max(correlation2)

    corr_peak_index3 = np.argmax(correlation3)
    corr_max3 = np.max(correlation3)

    offset1 = corr_peak_index1-(center_padded_trace.size-1)
    offset2 = corr_peak_index2-(center_padded_trace.size-1)
    offset3 = corr_peak_index3-(center_padded_trace.size-1)

    return offset1, offset2, offset3

    print("Corr1: {}, Corr2: {}, Corr3: {}".format(corr_peak_index1, corr_peak_index2, corr_peak_index3))
    print("Offset1: {}, Offset2: {}, Offset3: {}".format(offset1, offset2, offset3))

    plt.figure(1)

    plt.subplot(311)
    plt.plot(range(0, center_padded_trace.size), center_padded_trace, 'r-',
            range(offset1, left_padded_trace.size+offset1), left_padded_trace, 'b--',
            range(0, correlation1.size), correlation1/corr_max1, 'g-',
            [corr_peak_index1], [1], 'k+')

    plt.subplot(312)
    plt.plot(range(0, center_padded_trace.size), center_padded_trace, 'r-',
            range(offset2, center_padded_trace.size+offset2), center_padded_trace, 'b--',
            range(0, correlation2.size), correlation2/corr_max2, 'g-',
            [corr_peak_index2], [1], 'k+')

    plt.subplot(313)
    plt.plot(range(0, center_padded_trace.size), center_padded_trace, 'r-',
            range(offset3, right_padded_trace.size+offset3), right_padded_trace, 'b--',
            range(0, correlation3.size), correlation3/corr_max3, 'g-',
            [corr_peak_index3], [1], 'k+')

    plt.show()


x = np.arange(200)*0.01
y1 = np.array([*map(_main, x)])

y2 = np.array([*map(_main, x, np.ones(x.size,int))])

plt.figure(1)
plt.subplot(211)
plt.title('synthetic')
plt.plot(x,y1)
plt.legend(('left-shifted input', 'centered input', 'right-shifted input'))
plt.subplot(212)
plt.title('natural')
plt.plot(x,y2)
plt.ylabel('x-offset of result')
plt.xlabel('y-offset')
plt.savefig("summary.png")