Numpy 计算xarray中每个网格点的百分位数

Numpy 计算xarray中每个网格点的百分位数,numpy,multidimensional-array,probability,python-xarray,percentile,Numpy,Multidimensional Array,Probability,Python Xarray,Percentile,我目前正在使用xarray制作概率图。我想使用统计评估,比如“计数”练习。也就是说,对于NEU中的所有数据点,计算两个变量共同超过其阈值的次数。这意味着降水数据的第1个百分位和温度数据的第99个百分位。那么连接发生的概率(P)就是连接超出的数量除以数据集中的数据点数量 <xarray.Dataset> Dimensions: (latitude: 88, longitude: 200, time: 6348) Coordinates: * latitude (latit

我目前正在使用xarray制作概率图。我想使用统计评估,比如“计数”练习。也就是说,对于NEU中的所有数据点,计算两个变量共同超过其阈值的次数。这意味着降水数据的第1个百分位和温度数据的第99个百分位。那么连接发生的概率(P)就是连接超出的数量除以数据集中的数据点数量

<xarray.Dataset>
Dimensions:    (latitude: 88, longitude: 200, time: 6348)
Coordinates:
  * latitude   (latitude) float64 49.62 49.88 50.12 50.38 ... 70.88 71.12 71.38
  * longitude  (longitude) float64 -9.875 -9.625 -9.375 ... 39.38 39.62 39.88
  * time       (time) datetime64[ns] 1950-06-01 1950-06-02 ... 2018-08-31
Data variables:
    rr         (time, latitude, longitude) float32 dask.array<chunksize=(6348, 88, 200), meta=np.ndarray>
    tx         (time, latitude, longitude) float32 dask.array<chunksize=(6348, 88, 200), meta=np.ndarray>
    Ellipsis   float64 0.0

有人能帮我解决这个问题吗。我还尝试使用xr.apply_ufunc,但不幸的是,它的效果不好。

我不确定您希望如何处理分位数,但这里有一个版本,您可以从中进行调整

此外,我选择在计算分位数时保留数据集结构,因为它显示了如果异常值与数据相关,如何检索异常值(这离检索可能相关的有效数据点的值还有一步之遥)

1.创建一些数据 查看数据:

<xarray.Dataset>
Dimensions:        (latitude: 80, longitude: 120, time: 500)
Coordinates:
  * time           (time) int64 0 1 2 3 ... 496 497 498 499
  * latitude       (latitude) int64 0 1 2 3 ... 76 77 78 79
  * longitude      (longitude) int64 0 1 2 3 ... 117 118 119
Data variables:
    precipitation  (time, latitude, longitude) float64 -1.673 ... -0.3323
    temperature    (time, latitude, longitude) float64 -0.331 ... -0.03728
这是一个数据集,分析维度(“纬度”、“经度”)丢失,并且具有新的“分位数”维度:

<xarray.Dataset>
Dimensions:        (quantile: 2, time: 500)
Coordinates:
  * time           (time) int64 0 1 2 3 ... 496 497 498 499
  * quantile       (quantile) float64 0.1 0.9
Data variables:
    precipitation  (quantile, time) float64 -1.305 ... 1.264
    temperature    (quantile, time) float64 -1.267 ... 1.254
输出为布尔数据数组:

<xarray.DataArray (time: 500, latitude: 80, longitude: 120)>
array([[[False, ...]]])
Coordinates:
  * time       (time) int64 0 1 2 3 4 ... 496 497 498 499
  * latitude   (latitude) int64 0 1 2 3 4 ... 75 76 77 78 79
  * longitude  (longitude) int64 0 1 2 3 ... 116 117 118 119
4.计算每个时间步的异常值 最后,这里是仅具有时间维度的DataArray,其值为每个时间戳的异常值数量

<xarray.DataArray (time: 500)>
array([857, ...])
Coordinates:
  * time     (time) int64 0 1 2 3 4 ... 495 496 497 498 499

数组([857,…)
协调:
*时间(时间)int64 01 2 3 4。。。495 496 497 498 499
默认情况下,展平阵列可以工作,但是,在本例中,目标是只减少第一个维度,生成包含每个网格点结果的二维阵列。为此,可以使用
nanpercentile
axis
参数:

np.nanpercentile(NEU.rr, 1, axis=0)
但是,这将删除标记的尺寸和坐标。它是为了保留必须使用的DIM和坐标,
apply_ufunc
,它不会为您矢量化函数

xr.apply_ufunc(
    lambda x: np.nanpercentile(x, 1, axis=-1), NEU.rr, input_core_dims=[["time"]]
)

请注意,现在轴是
-1
,我们使用的是
输入核心dims
,它告诉
apply\u ufunc
此尺寸将减小,并将其移动到最后一个位置(因此
-1
)。有关
apply\ufunc
的更多详细说明,请参阅本指南。

谢谢您的提示!我对代码行进行了一点转换,只计算每个网格点的时间维度上的分位数<代码>qt_dims=(“时间”)qt_值=(0.01,0.99)ds_qt=SEU.quantile(qt_值,dim=qt_dims)#ds_qt.values da_outliers_loc=np.logical_和(SEU.rr ds_qt.tx.sel(quantile=qt_值[1]),da_seupt=da_outliers_loc sum(dim='time')/6348
<xarray.DataArray (time: 500, latitude: 80, longitude: 120)>
array([[[False, ...]]])
Coordinates:
  * time       (time) int64 0 1 2 3 4 ... 496 497 498 499
  * latitude   (latitude) int64 0 1 2 3 4 ... 75 76 77 78 79
  * longitude  (longitude) int64 0 1 2 3 ... 116 117 118 119
ds_outliers = ds.where(
    (ds.precipitation > ds_qt.precipitation.sel(quantile=qt_values[0]))
    & (ds.temperature > ds_qt.temperature.sel(quantile=qt_values[1]))
)
outliers_count = da_outliers_loc.sum(dim=qt_dims)
<xarray.DataArray (time: 500)>
array([857, ...])
Coordinates:
  * time     (time) int64 0 1 2 3 4 ... 495 496 497 498 499
np.nanpercentile(NEU.rr, 1, axis=0)
xr.apply_ufunc(
    lambda x: np.nanpercentile(x, 1, axis=-1), NEU.rr, input_core_dims=[["time"]]
)