使用XArray滚动分位数

时间:2019-02-09 14:36:39

标签: python quantile python-xarray

xArray窗口上是否有一种DataArray.rolling计算分位数的方法?列出的可用方法包括meanmedian,但分位数/百分位数没有。我想知道即使没有直接方法也可以通过某种方式完成。

当前,我正在将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'

请注意,由于在滚动对象上调用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 s,而construct运行耗时1.25 s。

1 个答案:

答案 0 :(得分:3)

您可以使用滚动对象的construct method,它会生成一个具有滚动尺寸的新DataArray

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

上面,我构建了一个具有附加tmp维的DataArray并沿该维计算分位数。