xarray: простой пример скользящего среднего с использованием .construct () - PullRequest
0 голосов
/ 25 мая 2018

Xarray может делать взвешенное скользящее среднее через объект .construct(), как указано в ответе на SO здесь , а также в документах .

Средневзвешенное скользящее среднееПример в документации выглядит не совсем правильно, поскольку он дает тот же ответ, что и обычное скользящее среднее.

import xarray as xr
import numpy as np

arr = xr.DataArray(np.arange(0, 7.5, 0.5).reshape(3, 5),
...                dims=('x', 'y'))
arr.rolling(y=3, center=True).mean()
#<xarray.DataArray (x: 3, y: 5)>
#array([[nan, 0.5, 1. , 1.5, nan],
#       [nan, 3. , 3.5, 4. , nan],
#       [nan, 5.5, 6. , 6.5, nan]])
#Dimensions without coordinates: x, y

weight = xr.DataArray([0.25, 0.5, 0.25], dims=['window'])
arr.rolling(y=3, center=True).construct('window').dot(weight)
#<xarray.DataArray (x: 3, y: 5)>
#array([[nan, 0.5, 1. , 1.5, nan],
#       [nan, 3. , 3.5, 4. , nan],
#       [nan, 5.5, 6. , 6.5, nan]])
#Dimensions without coordinates: x, y

Вот более простой пример, на котором я хотел бы получить правильный синтаксис:

da = xr.DataArray(np.arange(1,6), dims='x')
da.rolling(x=3, center=True).mean()
#<xarray.DataArray (x: 5)>
#array([nan,  2.,  3.,  4., nan])
#Dimensions without coordinates: x

weight = xr.DataArray([0.5, 1, 0.5], dims=['window'])
da.rolling(x=3, center=True).construct('window').dot(weight)
#<xarray.DataArray (x: 5)>
#array([nan,  4.,  6.,  8., nan])
#Dimensions without coordinates: x

Возвращает 4, 6, 8. Я думал, что это будет делать:

(1 x 0.5) + (2 x 1) + (3 x 0.5) / 3 = 4/3
(2 x 0.5) + (3 x 1) + (4 x 0.5) / 3 = 2
(3 x 0.5) + (4 x 1) + (5 x 0.5) / 3 = 8/3
1.33, 2. 2.66

1 Ответ

0 голосов
/ 25 мая 2018

В первом примере вы используете равномерно распределенные данные для arr.Следовательно, взвешенное среднее (с [0,25, 5, 0,25]) будет таким же, как простое mean.

Если вы рассматриваете нелинейные данные, результат отличается

In [50]: arr = xr.DataArray((np.arange(0, 7.5, 0.5)**2).reshape(3, 5),
    ...:                    dims=('x', 'y'))
    ...:                    

In [51]: arr.rolling(y=3, center=True).mean()
Out[51]: 
<xarray.DataArray (x: 3, y: 5)>
array([[      nan,  0.416667,  1.166667,  2.416667,       nan],
       [      nan,  9.166667, 12.416667, 16.166667,       nan],
       [      nan, 30.416667, 36.166667, 42.416667,       nan]])
Dimensions without coordinates: x, y

In [52]: weight = xr.DataArray([0.25, 0.5, 0.25], dims=['window'])
    ...: arr.rolling(y=3, center=True).construct('window').dot(weight)
    ...: 
Out[52]: 
<xarray.DataArray (x: 3, y: 5)>
array([[   nan,  0.375,  1.125,  2.375,    nan],
       [   nan,  9.125, 12.375, 16.125,    nan],
       [   nan, 30.375, 36.125, 42.375,    nan]])
Dimensions without coordinates: x, y

Для второго примера вы используете [0,5, 1, 0,5] в качестве веса, общее количество которого равно 2. Следовательно, первый элемент, отличный от наноса, будет (1 x 0.5) + (2 x 1) + (3 x 0.5) = 4

Если вы хотите средневзвешенное значениевместо взвешенной суммы используйте вместо этого [0.25, 0.5, 0.25].

...