def acf(x, nlags, fft=False, norm=True): ''' This is a modified module of statsmodels.tsa.stattools.acf from http://statsmodels.sourceforge.net/stable/index.html, which is statistical module specific for time series. Autocorrelation function for 1d arrays. Parameters ---------- x : array Time series data nlags: int, optional Number of lags to return autocorrelation for. Returns ------- acf : array autocorrelation function Notes ----- The acf at lag 0 (ie., 1) is returned. ''' assert fft from statsmodels.compat.scipy import _next_regular nobs = len(x) d = nobs # changes if unbiased x = np.squeeze(np.asarray(x)) #JP: move to acovf x0 = x - x.mean() # ensure that we always use a power of 2 or 3 for zero-padding, # this way we'll ensure O(n log n) runtime of the fft. n = _next_regular(2 * nobs + 1) Frf = np.fft.fft(x0, n=n) # zero-pad for separability acf = np.fft.ifft(Frf * np.conjugate(Frf))[:nobs] / d if norm: acf /= acf[0] return np.real(acf[:nlags + 1])
def test_next_regular(): hams = { 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 8, 8: 8, 14: 15, 15: 15, 16: 16, 17: 18, 1021: 1024, 1536: 1536, 51200000: 51200000, 510183360: 510183360, 510183360 + 1: 512000000, 511000000: 512000000, 854296875: 854296875, 854296875 + 1: 859963392, 196608000000: 196608000000, 196608000000 + 1: 196830000000, 8789062500000: 8789062500000, 8789062500000 + 1: 8796093022208, 206391214080000: 206391214080000, 206391214080000 + 1: 206624260800000, 470184984576000: 470184984576000, 470184984576000 + 1: 470715894135000, 7222041363087360: 7222041363087360, 7222041363087360 + 1: 7230196133913600, # power of 5 5**23 11920928955078125: 11920928955078125, 11920928955078125 - 1: 11920928955078125, # power of 3 3**34 16677181699666569: 16677181699666569, 16677181699666569 - 1: 16677181699666569, # power of 2 2**54 18014398509481984: 18014398509481984, 18014398509481984 - 1: 18014398509481984, # above this, int(ceil(n)) == int(ceil(n+1)) 19200000000000000: 19200000000000000, 19200000000000000 + 1: 19221679687500000, 288230376151711744: 288230376151711744, 288230376151711744 + 1: 288325195312500000, 288325195312500000 - 1: 288325195312500000, 288325195312500000: 288325195312500000, 288325195312500000 + 1: 288555831593533440, # power of 3 3**83 3**83 - 1: 3**83, 3**83: 3**83, # power of 2 2**135 2**135 - 1: 2**135, 2**135: 2**135, # power of 5 5**57 5**57 - 1: 5**57, 5**57: 5**57, # http://www.drdobbs.com/228700538 # 2**96 * 3**1 * 5**13 2**96 * 3**1 * 5**13 - 1: 2**96 * 3**1 * 5**13, 2**96 * 3**1 * 5**13: 2**96 * 3**1 * 5**13, 2**96 * 3**1 * 5**13 + 1: 2**43 * 3**11 * 5**29, # 2**36 * 3**69 * 5**7 2**36 * 3**69 * 5**7 - 1: 2**36 * 3**69 * 5**7, 2**36 * 3**69 * 5**7: 2**36 * 3**69 * 5**7, 2**36 * 3**69 * 5**7 + 1: 2**90 * 3**32 * 5**9, # 2**37 * 3**44 * 5**42 2**37 * 3**44 * 5**42 - 1: 2**37 * 3**44 * 5**42, 2**37 * 3**44 * 5**42: 2**37 * 3**44 * 5**42, 2**37 * 3**44 * 5**42 + 1: 2**20 * 3**106 * 5**7, } for x, y in hams.items(): assert_equal(_next_regular(x), y)
def acf(x, unbiased=False, nlags=40, confint=None, qstat=False, fft=False, alpha=None): ''' Autocorrelation function for 1d arrays. Parameters ---------- x : array Time series data unbiased : bool If True, then denominators for autocovariance are n-k, otherwise n nlags: int, optional Number of lags to return autocorrelation for. confint : scalar, optional The use of confint is deprecated. See `alpha`. If a number is given, the confidence intervals for the given level are returned. For instance if confint=95, 95 % confidence intervals are returned where the standard deviation is computed according to Bartlett\'s formula. qstat : bool, optional If True, returns the Ljung-Box q statistic for each autocorrelation coefficient. See q_stat for more information. fft : bool, optional If True, computes the ACF via FFT. alpha : scalar, optional If a number is given, the confidence intervals for the given level are returned. For instance if alpha=.05, 95 % confidence intervals are returned where the standard deviation is computed according to Bartlett\'s formula. Returns ------- acf : array autocorrelation function confint : array, optional Confidence intervals for the ACF. Returned if confint is not None. qstat : array, optional The Ljung-Box Q-Statistic. Returned if q_stat is True. pvalues : array, optional The p-values associated with the Q-statistics. Returned if q_stat is True. Notes ----- The acf at lag 0 (ie., 1) is returned. This is based np.correlate which does full convolution. For very long time series it is recommended to use fft convolution instead. If unbiased is true, the denominator for the autocovariance is adjusted but the autocorrelation is not an unbiased estimtor. ''' nobs = len(x) d = nobs # changes if unbiased if not fft: avf = acovf(x, unbiased=unbiased, demean=True) #acf = np.take(avf/avf[0], range(1,nlags+1)) acf = avf[:nlags + 1] / avf[0] else: #JP: move to acovf x0 = x - x.mean() # ensure that we always use a power of 2 or 3 for zero-padding, # this way we'll ensure O(n log n) runtime of the fft. n = _next_regular(2 * nobs + 1) Frf = np.fft.fft(x0, n=n) # zero-pad for separability if unbiased: d = nobs - np.arange(nobs) acf = np.fft.ifft(Frf * np.conjugate(Frf))[:nobs] / d acf /= acf[0] #acf = np.take(np.real(acf), range(1,nlags+1)) acf = np.real(acf[:nlags + 1]) # keep lag 0 if not (confint or qstat or alpha): return acf if not confint is None: import warnings warnings.warn("confint is deprecated. Please use the alpha keyword", FutureWarning) varacf = np.ones(nlags + 1) / nobs varacf[0] = 0 varacf[1] = 1. / nobs varacf[2:] *= 1 + 2 * np.cumsum(acf[1:-1]**2) interval = stats.norm.ppf(1 - (100 - confint) / 200.) * np.sqrt(varacf) confint = np.array(lzip(acf - interval, acf + interval)) if not qstat: return acf, confint if alpha is not None: varacf = np.ones(nlags + 1) / nobs varacf[0] = 0 varacf[1] = 1. / nobs varacf[2:] *= 1 + 2 * np.cumsum(acf[1:-1]**2) interval = stats.norm.ppf(1 - alpha / 2.) * np.sqrt(varacf) confint = np.array(lzip(acf - interval, acf + interval)) if not qstat: return acf, confint if qstat: qstat, pvalue = q_stat(acf[1:], nobs=nobs) # drop lag 0 if (confint is not None or alpha is not None): return acf, confint, qstat, pvalue else: return acf, qstat, pvalue
def acovf(x, unbiased=False, demean=True, fft=False, missing='none'): """ Autocovariance for 1D Parameters ---------- x : array Time series data. Must be 1d. unbiased : bool If True, then denominators is n-k, otherwise n demean : bool If True, then subtract the mean x from each element of x fft : bool If True, use FFT convolution. This method should be preferred for long time series. missing : str A string in ['none', 'raise', 'conservative', 'drop'] specifying how the NaNs are to be treated. Returns ------- acovf : array autocovariance function References ----------- .. [*] Parzen, E., 1963. On spectral analysis with missing observations and amplitude modulation. Sankhya: The Indian Journal of Statistics, Series A, pp.383-392. """ x = np.squeeze(np.asarray(x)) if x.ndim > 1: raise ValueError("x must be 1d. Got %d dims." % x.ndim) missing = missing.lower() if missing not in ['none', 'raise', 'conservative', 'drop']: raise ValueError("missing option %s not understood" % missing) if missing == 'none': deal_with_masked = False else: deal_with_masked = has_missing(x) if deal_with_masked: if missing == 'raise': raise MissingDataError("NaNs were encountered in the data") notmask_bool = ~np.isnan(x) #bool if missing == 'conservative': x[~notmask_bool] = 0 else: #'drop' x = x[notmask_bool] #copies non-missing notmask_int = notmask_bool.astype(int) #int if demean and deal_with_masked: # whether 'drop' or 'conservative': xo = x - x.sum()/notmask_int.sum() if missing=='conservative': xo[~notmask_bool] = 0 elif demean: xo = x - x.mean() else: xo = x n = len(x) if unbiased and deal_with_masked and missing=='conservative': d = np.correlate(notmask_int, notmask_int, 'full') elif unbiased: xi = np.arange(1, n + 1) d = np.hstack((xi, xi[:-1][::-1])) elif deal_with_masked: #biased and NaNs given and ('drop' or 'conservative') d = notmask_int.sum() * np.ones(2*n-1) else: #biased and no NaNs or missing=='none' d = n * np.ones(2 * n - 1) if fft: nobs = len(xo) n = _next_regular(2 * nobs + 1) Frf = np.fft.fft(xo, n=n) acov = np.fft.ifft(Frf * np.conjugate(Frf))[:nobs] / d[nobs - 1:] acov = acov.real else: acov = (np.correlate(xo, xo, 'full') / d)[n - 1:] if deal_with_masked and missing=='conservative': # restore data for the user x[~notmask_bool] = np.nan return acov
def acovf(x, unbiased=False, demean=True, fft=False, missing='none'): """ Autocovariance for 1D Parameters ---------- x : array Time series data. Must be 1d. unbiased : bool If True, then denominators is n-k, otherwise n demean : bool If True, then subtract the mean x from each element of x fft : bool If True, use FFT convolution. This method should be preferred for long time series. missing : str A string in ['none', 'raise', 'conservative', 'drop'] specifying how the NaNs are to be treated. Returns ------- acovf : array autocovariance function References ----------- .. [1] Parzen, E., 1963. On spectral analysis with missing observations and amplitude modulation. Sankhya: The Indian Journal of Statistics, Series A, pp.383-392. """ x = np.squeeze(np.asarray(x)) if x.ndim > 1: raise ValueError("x must be 1d. Got %d dims." % x.ndim) missing = missing.lower() if missing not in ['none', 'raise', 'conservative', 'drop']: raise ValueError("missing option %s not understood" % missing) if missing == 'none': deal_with_masked = False else: deal_with_masked = has_missing(x) if deal_with_masked: if missing == 'raise': raise MissingDataError("NaNs were encountered in the data") notmask_bool = ~np.isnan(x) #bool if missing == 'conservative': x[~notmask_bool] = 0 else: #'drop' x = x[notmask_bool] #copies non-missing notmask_int = notmask_bool.astype(int) #int if demean and deal_with_masked: # whether 'drop' or 'conservative': xo = x - x.sum()/notmask_int.sum() if missing=='conservative': xo[~notmask_bool] = 0 elif demean: xo = x - x.mean() else: xo = x n = len(x) if unbiased and deal_with_masked and missing=='conservative': d = np.correlate(notmask_int, notmask_int, 'full') elif unbiased: xi = np.arange(1, n + 1) d = np.hstack((xi, xi[:-1][::-1])) elif deal_with_masked: #biased and NaNs given and ('drop' or 'conservative') d = notmask_int.sum() * np.ones(2*n-1) else: #biased and no NaNs or missing=='none' d = n * np.ones(2 * n - 1) if fft: nobs = len(xo) n = _next_regular(2 * nobs + 1) Frf = np.fft.fft(xo, n=n) acov = np.fft.ifft(Frf * np.conjugate(Frf))[:nobs] / d[nobs - 1:] acov = acov.real else: acov = (np.correlate(xo, xo, 'full') / d)[n - 1:] if deal_with_masked and missing=='conservative': # restore data for the user x[~notmask_bool] = np.nan return acov
def acf(x, unbiased=False, nlags=40, confint=None, qstat=False, fft=False, alpha=None): ''' Autocorrelation function for 1d arrays. Parameters ---------- x : array Time series data unbiased : bool If True, then denominators for autocovariance are n-k, otherwise n nlags: int, optional Number of lags to return autocorrelation for. confint : scalar, optional The use of confint is deprecated. See `alpha`. If a number is given, the confidence intervals for the given level are returned. For instance if confint=95, 95 % confidence intervals are returned where the standard deviation is computed according to Bartlett\'s formula. qstat : bool, optional If True, returns the Ljung-Box q statistic for each autocorrelation coefficient. See q_stat for more information. fft : bool, optional If True, computes the ACF via FFT. alpha : scalar, optional If a number is given, the confidence intervals for the given level are returned. For instance if alpha=.05, 95 % confidence intervals are returned where the standard deviation is computed according to Bartlett\'s formula. Returns ------- acf : array autocorrelation function confint : array, optional Confidence intervals for the ACF. Returned if confint is not None. qstat : array, optional The Ljung-Box Q-Statistic. Returned if q_stat is True. pvalues : array, optional The p-values associated with the Q-statistics. Returned if q_stat is True. Notes ----- The acf at lag 0 (ie., 1) is returned. This is based np.correlate which does full convolution. For very long time series it is recommended to use fft convolution instead. If unbiased is true, the denominator for the autocovariance is adjusted but the autocorrelation is not an unbiased estimtor. ''' nobs = len(x) d = nobs # changes if unbiased if not fft: avf = acovf(x, unbiased=unbiased, demean=True) #acf = np.take(avf/avf[0], range(1,nlags+1)) acf = avf[:nlags + 1] / avf[0] else: x = np.squeeze(np.asarray(x)) #JP: move to acovf x0 = x - x.mean() # ensure that we always use a power of 2 or 3 for zero-padding, # this way we'll ensure O(n log n) runtime of the fft. n = _next_regular(2 * nobs + 1) Frf = np.fft.fft(x0, n=n) # zero-pad for separability if unbiased: d = nobs - np.arange(nobs) acf = np.fft.ifft(Frf * np.conjugate(Frf))[:nobs] / d acf /= acf[0] #acf = np.take(np.real(acf), range(1,nlags+1)) acf = np.real(acf[:nlags + 1]) # keep lag 0 if not (confint or qstat or alpha): return acf if not confint is None: import warnings warnings.warn("confint is deprecated. Please use the alpha keyword", FutureWarning) varacf = np.ones(nlags + 1) / nobs varacf[0] = 0 varacf[1] = 1. / nobs varacf[2:] *= 1 + 2 * np.cumsum(acf[1:-1]**2) interval = stats.norm.ppf(1 - (100 - confint) / 200.) * np.sqrt(varacf) confint = np.array(lzip(acf - interval, acf + interval)) if not qstat: return acf, confint if alpha is not None: varacf = np.ones(nlags + 1) / nobs varacf[0] = 0 varacf[1] = 1. / nobs varacf[2:] *= 1 + 2 * np.cumsum(acf[1:-1]**2) interval = stats.norm.ppf(1 - alpha / 2.) * np.sqrt(varacf) confint = np.array(lzip(acf - interval, acf + interval)) if not qstat: return acf, confint if qstat: qstat, pvalue = q_stat(acf[1:], nobs=nobs) # drop lag 0 if (confint is not None or alpha is not None): return acf, confint, qstat, pvalue else: return acf, qstat, pvalue
def test_next_regular(): hams = { 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 8, 8: 8, 14: 15, 15: 15, 16: 16, 17: 18, 1021: 1024, 1536: 1536, 51200000: 51200000, 510183360: 510183360, 510183360 + 1: 512000000, 511000000: 512000000, 854296875: 854296875, 854296875 + 1: 859963392, 196608000000: 196608000000, 196608000000 + 1: 196830000000, 8789062500000: 8789062500000, 8789062500000 + 1: 8796093022208, 206391214080000: 206391214080000, 206391214080000 + 1: 206624260800000, 470184984576000: 470184984576000, 470184984576000 + 1: 470715894135000, 7222041363087360: 7222041363087360, 7222041363087360 + 1: 7230196133913600, # power of 5 5**23 11920928955078125: 11920928955078125, 11920928955078125 - 1: 11920928955078125, # power of 3 3**34 16677181699666569: 16677181699666569, 16677181699666569 - 1: 16677181699666569, # power of 2 2**54 18014398509481984: 18014398509481984, 18014398509481984 - 1: 18014398509481984, # above this, int(ceil(n)) == int(ceil(n+1)) 19200000000000000: 19200000000000000, 19200000000000000 + 1: 19221679687500000, 288230376151711744: 288230376151711744, 288230376151711744 + 1: 288325195312500000, 288325195312500000 - 1: 288325195312500000, 288325195312500000: 288325195312500000, 288325195312500000 + 1: 288555831593533440, # power of 3 3**83 3990838394187339929534246675572349035227 - 1: 3990838394187339929534246675572349035227, 3990838394187339929534246675572349035227: 3990838394187339929534246675572349035227, # power of 2 2**135 43556142965880123323311949751266331066368 - 1: 43556142965880123323311949751266331066368, 43556142965880123323311949751266331066368: 43556142965880123323311949751266331066368, # power of 5 5**57 6938893903907228377647697925567626953125 - 1: 6938893903907228377647697925567626953125, 6938893903907228377647697925567626953125: 6938893903907228377647697925567626953125, # http://www.drdobbs.com/228700538 # 2**96 * 3**1 * 5**13 290142196707511001929482240000000000000 - 1: 290142196707511001929482240000000000000, 290142196707511001929482240000000000000: 290142196707511001929482240000000000000, 290142196707511001929482240000000000000 + 1: 290237644800000000000000000000000000000, # 2**36 * 3**69 * 5**7 4479571262811807241115438439905203543080960000000 - 1: 4479571262811807241115438439905203543080960000000, 4479571262811807241115438439905203543080960000000: 4479571262811807241115438439905203543080960000000, 4479571262811807241115438439905203543080960000000 + 1: 4480327901140333639941336854183943340032000000000, # 2**37 * 3**44 * 5**42 30774090693237851027531250000000000000000000000000000000000000 - 1: 30774090693237851027531250000000000000000000000000000000000000, 30774090693237851027531250000000000000000000000000000000000000: 30774090693237851027531250000000000000000000000000000000000000, 30774090693237851027531250000000000000000000000000000000000000 + 1: 30778180617309082445871527002041377406962596539492679680000000, } for x, y in hams.items(): assert_equal(_next_regular(x), y)
def test_next_regular(): hams = { 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 8, 8: 8, 14: 15, 15: 15, 16: 16, 17: 18, 1021: 1024, 1536: 1536, 51200000: 51200000, 510183360: 510183360, 510183360+1: 512000000, 511000000: 512000000, 854296875: 854296875, 854296875+1: 859963392, 196608000000: 196608000000, 196608000000+1: 196830000000, 8789062500000: 8789062500000, 8789062500000+1: 8796093022208, 206391214080000: 206391214080000, 206391214080000+1: 206624260800000, 470184984576000: 470184984576000, 470184984576000+1: 470715894135000, 7222041363087360: 7222041363087360, 7222041363087360+1: 7230196133913600, # power of 5 5**23 11920928955078125: 11920928955078125, 11920928955078125-1: 11920928955078125, # power of 3 3**34 16677181699666569: 16677181699666569, 16677181699666569-1: 16677181699666569, # power of 2 2**54 18014398509481984: 18014398509481984, 18014398509481984-1: 18014398509481984, # above this, int(ceil(n)) == int(ceil(n+1)) 19200000000000000: 19200000000000000, 19200000000000000+1: 19221679687500000, 288230376151711744: 288230376151711744, 288230376151711744+1: 288325195312500000, 288325195312500000-1: 288325195312500000, 288325195312500000: 288325195312500000, 288325195312500000+1: 288555831593533440, # power of 3 3**83 3990838394187339929534246675572349035227-1: 3990838394187339929534246675572349035227, 3990838394187339929534246675572349035227: 3990838394187339929534246675572349035227, # power of 2 2**135 43556142965880123323311949751266331066368-1: 43556142965880123323311949751266331066368, 43556142965880123323311949751266331066368: 43556142965880123323311949751266331066368, # power of 5 5**57 6938893903907228377647697925567626953125-1: 6938893903907228377647697925567626953125, 6938893903907228377647697925567626953125: 6938893903907228377647697925567626953125, # http://www.drdobbs.com/228700538 # 2**96 * 3**1 * 5**13 290142196707511001929482240000000000000-1: 290142196707511001929482240000000000000, 290142196707511001929482240000000000000: 290142196707511001929482240000000000000, 290142196707511001929482240000000000000+1: 290237644800000000000000000000000000000, # 2**36 * 3**69 * 5**7 4479571262811807241115438439905203543080960000000-1: 4479571262811807241115438439905203543080960000000, 4479571262811807241115438439905203543080960000000: 4479571262811807241115438439905203543080960000000, 4479571262811807241115438439905203543080960000000+1: 4480327901140333639941336854183943340032000000000, # 2**37 * 3**44 * 5**42 30774090693237851027531250000000000000000000000000000000000000-1: 30774090693237851027531250000000000000000000000000000000000000, 30774090693237851027531250000000000000000000000000000000000000: 30774090693237851027531250000000000000000000000000000000000000, 30774090693237851027531250000000000000000000000000000000000000+1: 30778180617309082445871527002041377406962596539492679680000000, } for x, y in hams.items(): assert_equal(_next_regular(x), y)
def acovf(x, unbiased=False, demean=True, fft=None, missing='none', nlag=None): """ Autocovariance for 1D Parameters ---------- x : array Time series data. Must be 1d. unbiased : bool If True, then denominators is n-k, otherwise n demean : bool If True, then subtract the mean x from each element of x fft : bool If True, use FFT convolution. This method should be preferred for long time series. missing : str A string in ['none', 'raise', 'conservative', 'drop'] specifying how the NaNs are to be treated. nlag : {int, None} Limit the number of autocovariances returned. Size of returned array is nlag + 1. Setting nlag when fft is False uses a simple, direct estimator of the autocovariances that only computes the first nlag + 1 values. This can be much faster when the time series is long and only a small number of autocovariances are needed. Returns ------- acovf : array autocovariance function References ----------- .. [*] Parzen, E., 1963. On spectral analysis with missing observations and amplitude modulation. Sankhya: The Indian Journal of Statistics, Series A, pp.383-392. """ if fft is None: import warnings msg = 'fft=True will become the default in a future version of ' \ 'statsmodels. To suppress this warning, explicitly set ' \ 'fft=False.' warnings.warn(msg, FutureWarning) fft = False x = np.squeeze(np.asarray(x)) if x.ndim > 1: raise ValueError("x must be 1d. Got %d dims." % x.ndim) missing = missing.lower() if missing not in ['none', 'raise', 'conservative', 'drop']: raise ValueError("missing option %s not understood" % missing) if missing == 'none': deal_with_masked = False else: deal_with_masked = has_missing(x) if deal_with_masked: if missing == 'raise': raise MissingDataError("NaNs were encountered in the data") notmask_bool = ~np.isnan(x) # bool if missing == 'conservative': # Must copy for thread safety x = x.copy() x[~notmask_bool] = 0 else: # 'drop' x = x[notmask_bool] # copies non-missing notmask_int = notmask_bool.astype(int) # int if demean and deal_with_masked: # whether 'drop' or 'conservative': xo = x - x.sum() / notmask_int.sum() if missing == 'conservative': xo[~notmask_bool] = 0 elif demean: xo = x - x.mean() else: xo = x n = len(x) lag_len = nlag if nlag is None: lag_len = n - 1 elif nlag > n - 1: raise ValueError('nlag must be smaller than nobs - 1') if not fft and nlag is not None: acov = np.empty(lag_len + 1) acov[0] = xo.dot(xo) for i in range(lag_len): acov[i + 1] = xo[i + 1:].dot(xo[:-(i + 1)]) if not deal_with_masked or missing == 'drop': if unbiased: acov /= (n - np.arange(lag_len + 1)) else: acov /= n else: if unbiased: divisor = np.empty(lag_len + 1, dtype=np.int64) divisor[0] = notmask_int.sum() for i in range(lag_len): divisor[i + 1] = notmask_int[i + 1:].dot( notmask_int[:-(i + 1)]) divisor[divisor == 0] = 1 acov /= divisor else: # biased, missing data but npt 'drop' acov /= notmask_int.sum() return acov if unbiased and deal_with_masked and missing == 'conservative': d = np.correlate(notmask_int, notmask_int, 'full') d[d == 0] = 1 elif unbiased: xi = np.arange(1, n + 1) d = np.hstack((xi, xi[:-1][::-1])) elif deal_with_masked: # biased and NaNs given and ('drop' or 'conservative') d = notmask_int.sum() * np.ones(2 * n - 1) else: # biased and no NaNs or missing=='none' d = n * np.ones(2 * n - 1) if fft: nobs = len(xo) n = _next_regular(2 * nobs + 1) Frf = np.fft.fft(xo, n=n) acov = np.fft.ifft(Frf * np.conjugate(Frf))[:nobs] / d[nobs - 1:] acov = acov.real else: acov = np.correlate(xo, xo, 'full')[n - 1:] / d[n - 1:] if nlag is not None: # Copy to allow gc of full array rather than view return acov[:lag_len + 1].copy() return acov