Difference between normed plt.xcorr at 0-lag and np.corrcoef
<p>I am working on a cross correlation between two relatively small time series, but in trying to accomplish I am running into a problem I cannot reconcile myself. To begin, I understand the dependence between <code>plt.xcorr</code> and <code>np.correlate</code>. However, I am having trouble reconciling the difference between <code>plt.xcorr</code> at zero lag and <code>np.corrcoef</code>?</p>

<pre><code>a = np.array([  7.35846410e+08,   8.96271634e+08,   6.16249222e+08,
     8.00739868e+08,   1.06116376e+09,   9.05690167e+08,
     6.31383600e+08])
b = np.array([  1.95621617e+09,   2.06263134e+09,   2.27717015e+09,
     2.27281916e+09,   2.71090116e+09,   2.84676385e+09,
     3.19578883e+09])

np.corrcoef(a,b)
# returns:
array([[ 1.        ,  0.02099573],
      [ 0.02099573,  1.        ]])

plt.xcorr(a,b,normed=True, maxlags=1)
# returns:
array([-1,  0,  1]),
 array([ 0.90510941,  0.97024415,  0.79874158])
</code></pre>

<p>I expected these to return the same result. I clearly do not understand how <code>plt.xcorr</code> is normed, could someone please set me straight?</p>

<p>Calculation of standard "Pearson product-moment correlation coefficient" is using samples, shifted by mean values.
Cross-correlation coefficient doesn't use normalized samples.
Other than than, computation is similar. But still those coefficients have different formulas and different meaning. They are equal only if mean values of samples <code>a</code> and <code>b</code> are equal to <code>0</code> (if shifting by mean values doesn't change the samples.</p>

<pre><code>import numpy as np
import matplotlib.pyplot as plt

a = np.array([7.35846410e+08, 8.96271634e+08, 6.16249222e+08,
     8.00739868e+08, 1.06116376e+09, 9.05690167e+08, 6.31383600e+08])
b = np.array([1.95621617e+09, 2.06263134e+09, 2.27717015e+09,
     2.27281916e+09, 2.71090116e+09, 2.84676385e+09, 3.19578883e+09])

y = np.corrcoef(a, b)
z = plt.xcorr(a, b, normed=True, maxlags=1)
print("Pearson product-moment correlation coefficient between `a` and `b`:", y[0][1])
print("Cross-correlation coefficient between `a` and `b` with 0-lag:", z[1][1], "\n")


# Calculate manually:

def pearson(a, b):
    # Length.
    n = len(a)

    # Means.
    ma = sum(a) / n
    mb = sum(b) / n

    # Shifted samples.
    _ama = a - ma
    _bmb = b - mb

    # Standard deviations.
    sa = np.sqrt(np.dot(_ama, _ama) / n)
    sb = np.sqrt(np.dot(_bmb, _bmb) / n)

    # Covariation.
    cov = np.dot(_ama, _bmb) / n

    # Final formula.
    # Note: division by `n` in deviations and covariation cancel out each other in
    #       final formula and could be ignored.
    return cov / (sa * sb)

def cross0lag(a, b):
    return np.dot(a, b) / np.sqrt(np.dot(a, a) * np.dot(b, b))

pearson_coeff = pearson(a, b)
cross_coeff = cross0lag(a, b)

print("Manually calculated coefficients:")
print("  Pearson =", pearson_coeff)
print("  Cross   =", cross_coeff, "\n")


# Normalized samples:
am0 = a - sum(a) / len(a)
bm0 = b - sum(b) / len(b)
pearson_coeff = pearson(am0, bm0)
cross_coeff = cross0lag(am0, bm0)
print("Coefficients for samples with means = 0:")
print("  Pearson =", pearson_coeff)
print("  Cross   =", cross_coeff)
</code></pre>

<p><strong>Output:</strong></p>

<pre><code>Pearson product-moment correlation coefficient between `a` and `b`: 0.020995727082
Cross-correlation coefficient between `a` and `b` with 0-lag: 0.970244146831 

Manually calculated coefficients:
  Pearson = 0.020995727082
  Cross   = 0.970244146831 

Coefficients for samples with means = 0:
  Pearson = 0.020995727082
  Cross   = 0.020995727082
</code></pre>

python numpy correlation cross-correlation