Python交叉相关性

14

我有一对1D数组(长度不同),如下所示:

data1 = [0,0,0,1,1,1,0,1,0,0,1]
data2 = [0,1,1,0,1,0,0,1]

我想在Python中获得两个序列的最大交叉相关性。在Matlab中,xcorr()函数可以返回正确结果。

我尝试了以下两种方法:

  1. numpy.correlate(data1, data2)
  2. signal.fftconvolve(data2, data1[::-1], mode='full')

这两种方法都给出相同的值,但是我从Python获得的值与从Matlab获得的值不同。Python给出的整数值大于1,而Matlab给出的是0到1之间的实际相关值。

我尝试先对两个数组进行归一化(减去平均值除以标准差),但我得到的交叉相关值却是在千位数级别,这似乎不正确。

Matlab还会给出一个滞后值,在该滞后值下交叉相关性最大。如果我的数组包含数万个值,使用索引很容易做到这一点,但最合适的方法是什么?

我想模仿Matlab中的xcorr()函数,在Python中怎样实现呢?


请发布来自Matlab和两个Python库的实际值和期望值。 - Peter Gibson
参考此链接:https://dev59.com/zWw05IYBdhLWcg3w11W0 - Raghav RV
我之前看过那个帖子,已经尝试了所有的方法。numpy.correlate 给出的值在1-500之间。而 matplotlib 的 xcorr() 要求两个一维数组的长度相同(我的长度不同)。 - Simon
如果x和y的长度不相同,则较短的向量将被填充为零,以使其长度与较长的向量相同。这是Matlab xcorr文档中的说明。或许可以尝试结合matplotlib的xcorr使用? - Raghav RV
numpy的相关函数文档不够完善,真的很令人沮丧。至少应该添加一两个带有图示的示例。 - eric
3个回答

20
numpy.correlate(arr1,arr2,"full")

给了我相同的输出结果

xcorr(arr1,arr2)

在Matlab中的含义


2
你如何消除这个时间滞后? - bischoffingston
3
在numpy.correlate()中添加"full"参数即可达到效果。为了获取最大时间滞后,只需在correlate()返回值上调用argmax()函数即可。 - Simon
只是为了澄清,滞后值为0对应于输出数组的中心。因此,如果c = xcorr(arr1,arr2),则滞后值= argmax(c)- c.size / 2。 - argentum2f

5

实现MATLAB xcorr(x,y)函数,并将结果与示例进行比较。

import scipy.signal as signal
def xcorr(x,y):
    """
    Perform Cross-Correlation on x and y
    x    : 1st signal
    y    : 2nd signal

    returns
    lags : lags of correlation
    corr : coefficients of correlation
    """
    corr = signal.correlate(x, y, mode="full")
    lags = signal.correlation_lags(len(x), len(y), mode="full")
    return lags, corr

n = np.array([i for i in range(0,15)])
x = 0.84**n
y = np.roll(x,5);
lags,c = xcorr(x,y);
plt.figure()
plt.stem(lags,c)
plt.show()

output resembling matlab xcorr output


1
这段代码可以帮助找出音频文件中两个通道之间的延迟。
xin, fs = sf.read('recording1.wav')
frame_len = int(fs*5*1e-3)
dim_x =xin.shape
M = dim_x[0] # No. of rows
N= dim_x[1] # No. of col
sample_lim = frame_len*100
tau = [0]
M_lim = 20000 # for testing as processing takes time
for i in range(1,N):
    c = np.correlate(xin[0:M_lim,0],xin[0:M_lim,i],"full")
    maxlags = M_lim-1
    c = c[M_lim -1 -maxlags: M_lim + maxlags]
    Rmax_pos = np.argmax(c)
    pos = Rmax_pos-M_lim+1
    tau.append(pos)
print(tau)

虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅链接的答案可能会失效。- 来自审查 - ascripter
@ascripter 实际上这里有一个答案,不需要链接。 - Ajean
@Ajean 你说得对。这实际上是一个有价值的提示。 - ascripter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接