14

I have a pair of 1D arrays (of different lengths) like the following:

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

I would like to get the max cross correlation of the 2 series in python. In matlab, the xcorr() function will return it OK

I have tried the following 2 methods:

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

Both methods give me the same values, but the values I get from python are different from what comes out of matlab. Python gives me integers values > 1, whereas matlab gives actual correlation values between 0 and 1.

I have tried normalizing the 2 arrays first (value-mean/SD), but the cross correlation values I get are in the thousands which doesnt seem correct.

Matlab will also give you a lag value at which the cross correlation is the greatest. I assume it is easy to do this using indices but whats the most appropriate way of doing this if my arrays contain 10's of thousands of values?

I would like to mimic the xcorr() function that matlab has, any thoughts on how I would do that in python?

Lukas Vrabel
  • 807
  • 9
  • 17
Simon
  • 9,762
  • 15
  • 62
  • 119
  • Please post actual and expected values from matlab and the 2 python libs – Peter Gibson Sep 14 '14 at 09:14
  • Refer this http://stackoverflow.com/questions/6991471/computing-cross-correlation-function – Raghav RV Sep 14 '14 at 18:11
  • I saw that thread a while ago and have tried all of those methods. numpy.correlate gives me values anywhere from 1-500. and matplotlib's xcorr() requires the 2 1D arrays to be of the same length (mine aren't) – Simon Sep 14 '14 at 23:44
  • "If x and y are not the same length, the shorter vector is zero-padded to the length of the longer vector." From Matlab's xcorr documentation. Perhaps try that along with the matplotlib's xcorr ? – Raghav RV Sep 15 '14 at 01:08
  • numpy's correlate is not well documented it is truly frustrating. at the very least an example or two should be added with figures. – eric Sep 29 '22 at 15:26

3 Answers3

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

gave me same output as

xcorr(arr1,arr2)

gives in matlab

Cheeku
  • 833
  • 1
  • 8
  • 22
5

Implementation of MATLAB xcorr(x,y) and comparision of result with example.

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

Dharman
  • 30,962
  • 25
  • 85
  • 135
codenio
  • 721
  • 10
  • 17
1

This code will help in finding the delay between two channels in audio file

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)
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/22475624) – ascripter Mar 15 '19 at 16:46
  • @ascripter Actually there is an answer here that doesn't require the link. – Ajean Mar 15 '19 at 21:21
  • @Ajean You're right. It's actually a valuable hint. – ascripter Mar 15 '19 at 21:25