随机遮罩/设置巨大xarray.DataArray中的nan x%的数据点

时间:2019-05-22 13:01:17

标签: python numpy dask python-xarray

我有一个庞大的(约20亿个数据点)xarray.DataArray。我想随机删除(用np.nan屏蔽或替换)给定百分比的数据,其中每个数据点被选择删除/屏蔽的概率在所有坐标上都相同。我可以将数组转换为numpy.array,但最好还是将其保留在dask块中以提高速度。

我的数据如下:

>> data
<xarray.DataArray 'stack-820860ba63bd07adc355885d96354267' (variable: 8, time: 228, latitude: 721, longitude: 1440)>
dask.array<stack, shape=(8, 228, 721, 1440), dtype=float64, chunksize=(1, 6, 721, 1440)>
Coordinates:
* latitude   (latitude) float32 90.0 89.75 89.5 89.25 89.0 88.75 88.5 ...
* variable   (variable) <U5 u'fal' u'swvl1' u'swvl3' u'e' u'swvl2' u'es' 
* longitude  (longitude) float32 0.0 0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0 
* time       (time) datetime64[ns] 2000-01-01 2000-02-01 2000-03-01 ...

我定义了

frac_missing = 0.2
k = int(frac_missing*data.size)

这是我已经尝试过的:

  • this solutionnp.ndindex一起使用,但是np.ndindex对象被转换为一个非常慢的列表。我尝试绕过转换,只是按照herehere所述在np.ndindex对象上进行迭代,但是在整个迭代器上进行迭代大约需要20亿个数据点。
  • np.random.choice(data.stack(newdim=('latitude','variable','longitude','time')),k,replace=False)返回所需的数据点子集,但未将其设置为nan

期望的输出将是xarray.DataArray,其中给定百分比的数据点设置为np.nan或被屏蔽,最好以相同的形状和相同的大块数据进行。

1 个答案:

答案 0 :(得分:0)

user545424的建议是一个很好的起点。为了避免遇到内存问题,可以将其放在一个小的用户定义函数中,并使用方法apply_ufunc将其映射到DataArray上。

import xarray as xr
import numpy as np

testdata = xr.DataArray(np.empty((100,1000,1000)), dims=['x','y','z'])

def set_random_fraction_to_nan(data):
    data[np.random.rand(*data.shape) < .8]=np.nan
    return data

# Set 80% of data randomly to nan
testdata = xr.apply_ufunc(set_random_fraction_to_nan, testdata, input_core_dims=[['x','y','z']],output_core_dims=[['x','y','z']], dask='parallelized')

有关包装自定义函数以使用xarray的更多说明,请参见here.