Your question 1 has been already extensively discussed in several excellent answers here.
I thought to share with you a few lines of code that allow you to compute the autocorrelation of a signal based only on the mathematical properties of the autocorrelation. That is, the autocorrelation may be computed in the following way:
subtract the mean from the signal and obtain an unbiased signal
compute the Fourier transform of the unbiased signal
compute the power spectral density of the signal, by taking the square norm of each value of the Fourier transform of the unbiased signal
compute the inverse Fourier transform of the power spectral density
normalize the inverse Fourier transform of the power spectral density by the sum of the squares of the unbiased signal, and take only half of the resulting vector
The code to do this is the following:
def autocorrelation (x) :
"""
Compute the autocorrelation of the signal, based on the properties of the
power spectral density of the signal.
"""
xp = x-np.mean(x)
f = np.fft.fft(xp)
p = np.array([np.real(v)**2+np.imag(v)**2 for v in f])
pi = np.fft.ifft(p)
return np.real(pi)[:x.size/2]/np.sum(xp**2)