случайным образом маскирует / устанавливает нано х% точек данных в огромном массиве xarray.DataArray - PullRequest
2 голосов
/ 22 мая 2019

У меня огромное (~ 2 миллиарда точек данных) xarray.DataArray. Я хотел бы случайно удалить (либо замаскировать, либо заменить на np.nan) определенный процент данных, где вероятность для каждой точки данных, которая будет выбрана для удаления / маскирования, одинакова во всех координатах. Я могу преобразовать массив в numpy.array, но я бы предпочел, чтобы он был быстрым.

мои данные выглядят так:

>> 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, как описано здесь и здесь , но итерация по всему итератору медленная для ~ 2 миллиардов точек данных.
  • np.random.choice(data.stack(newdim=('latitude','variable','longitude','time')),k,replace=False) возвращает желаемое подмножество точек данных, но не устанавливает для них значение nan

Ожидаемый результат будет xarray.DataArray с заданным процентом точек данных, либо установленным на np.nan, либо замаскированным, предпочтительно в той же форме и с теми же частями.

1 Ответ

0 голосов
/ 23 мая 2019

Предложение user545424 - отличное начало.Чтобы не сталкиваться с проблемами с памятью, вы можете поместить ее в небольшую пользовательскую функцию и отобразить ее в массив данных DataArray, используя метод 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 см. здесь.

...