我有一个巨大(约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)
这是我已经尝试的:
- 该解决方案可与
np.ndindex
一起使用,但np.ndindex
对象转换为非常慢的列表。我尝试绕过转换,并简单地在此处和此处描述的np.ndindex
对象进行迭代,但是在整个迭代器上进行迭代的数据点很慢。 -
np.random.choice(data.stack(newdim=('latitude','variable','longitude','time')),k,replace=False)
返回所需的数据点子集,但没有将它们设置为Nan
预期的输出将是xarray.DataArray
,具有设置为np.nan
或蒙版的给定百分比,最好是相同的形状和相同的Dask块。
用户545424的建议是一个很好的开始。为了不遇到内存问题,您可以将其放入小的用户定义函数中,并使用方法apply_ufunc
将其映射到数据隔间。
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一起使用的更多解释,请参见此处。