Я пытаюсь вычислить ACF для сетки временных рядов, используя python. statsmodels.acf
принимает только одномерные временные ряды, поэтому использование xr.apply_ufunc
, например, не является жизнеспособным решением. (Обратите внимание, что здесь я использую xarray
в качестве предпочтительного пакета, поскольку я имею дело с большими многомерными помеченными наборами данных)
Я подумал, что было бы проще написать ACF с нуля и векторизовать его. Обрезать statsmodels.acf
до скелета, который мне нужен:
from numpy import correlate as npc
from scipy.signal import correlate as spc
def acf(x, nlags=40):
"""
ds : xarray DataArray with gridded time series
e.g., dims ('time', 'lat', 'lon')
nlags : number of lags to compute ACF out to
"""
avf = acovf(x)
acf = avf[:nlags + 1] / avf[0]
return acf
def acovf(x):
xo = x - x.mean('time')
n = x['time'].size
lag_len = n - 1
d = n * np.ones(2 * n - 1)
acov = npc(xo, xo, 'full')[n - 1:] / d[n - 1:]
return acov
В данный момент это разрыв на линии npc
. np.correlate
, а также scipy.signal.correlate
прерывают с чем-то большим, чем 1-мерный временной ряд, или дают нежелательный ответ.
Наиболее прямо: Как я могу векторизовать дискретную линейную взаимную корреляцию многих временных рядов на сетке?
Используя пример:
x = xr.DataArray(np.random.rand(10,2,3), dims=['time', 'lat', 'lon'])
Если я запускаю npc(x, x, 'full')
, я получаю ошибку:
ValueError: object too deep for desired array
Если я запускаю spc(x, x)
, я получаю (19, 3, 5) массив, который не содержит точного вывода. Мой вывод должен быть (N * 2-1, широта, долгота), где N - количество временных выборок.
Эта проблема, похоже, является узким местом в векторизации ACF - если я могу заставить работать взаимную корреляцию, остальные функции acf
и acovf
должны быть простыми для векторизации.