Роллинг квантиль с xarray - PullRequest
       14

Роллинг квантиль с xarray

0 голосов
/ 09 февраля 2019

Есть ли xArray способ вычисления квантилей в DataArray.rolling окне?Перечисленные доступные методы включают mean или median, но ничего для квантилей / процентилей.Мне было интересно, можно ли это как-то сделать, хотя прямого пути нет.

В настоящее время я локально переносю данные xArray в pandas.DataFrame, где я применяю последовательность rolling().quantile().После этого я беру значения нового DataFrame и строю из него xArray.DataArray.Воспроизводимый код:

import xarray as xr
import pandas as pd
import numpy as np

times = np.arange(0, 30)
locs = ['A', 'B', 'C', 'D'] 

signal = xr.DataArray(np.random.rand(len(times), len(locs)), 
                      coords=[times, locs], dims=['time', 'locations'])
window = 5

df = pd.DataFrame(data=signal.data)
roll = df.rolling(window=window, center=True, axis=0).quantile(.25).dropna()
window_array = xr.DataArray(roll.values, 
            coords=[np.arange(0, signal.time.shape[0] - window + 1), signal.locations], 
            dims=['time', 'locations'])

Приветствуется любой ключ к максимально возможному увеличению xArray.

Давайте рассмотрим ту же проблему, только меньшую по размеру (10 раз,2 местоположения).

Вот ввод первого метода (через pandas):

<xarray.DataArray (time: 8, locations: 2)>
array([[0.404362, 0.076203],
       [0.353639, 0.076203],
       [0.387167, 0.102917],
       [0.525404, 0.298231],
       [0.755646, 0.298231],
       [0.460749, 0.414935],
       [0.104887, 0.498813],
       [0.104887, 0.420935]])
Coordinates:
* time       (time) int32 0 1 2 3 4 5 6 7
* locations  (locations) <U1 'A' 'B'

Обратите внимание, что измерение 'time' меньше из-за вызова dropna()на прокатном объекте.Новый размер измерения в основном len(times) - window + 1.Теперь вывод для предложенного метода (через construct):

<xarray.DataArray (time: 10, locations: 2)>
array([[0.438426, 0.127881],
       [0.404362, 0.076203],
       [0.353639, 0.076203],
       [0.387167, 0.102917],
       [0.525404, 0.298231],
       [0.755646, 0.298231],
       [0.460749, 0.414935],
       [0.104887, 0.498813],
       [0.104887, 0.420935],
       [0.112651, 0.60338 ]])
Coordinates:
* time       (time) int32 0 1 2 3 4 5 6 7 8 9
* locations  (locations) <U1 'A' 'B'

Кажется, что размеры все еще (time, locations), с размером первого, равным 10, а не 8. Впример здесь, так как center=True, два результата одинаковы, если вы удалите первую и последнюю строки во втором массиве.Разве у DataArray не должно быть нового измерения, tmp?

Кроме того, этот метод (с установленным bottleneck) занимает больше, чем тот, который первоначально предлагался через pandas.Например, на примере 1000 times x 2 locations прогон pandas занимает 0,015 с, а construct - 1,25 с.

1 Ответ

0 голосов
/ 10 февраля 2019

Вы можете использовать construct метод объекта прокатки, который генерирует новый DataArray с размером прокатки.

signal.rolling(time=window, center=True).construct('tmp').quantile(.25, dim='tmp')

Выше я построил DataArray с дополнительнымtmp измерение и вычисление квантиля вдоль этого измерения.

...