Итеративно заполняйте значения NaN в xarray с помощью dask

У меня есть большой трехмерный набор данных (y, x, время) со значительными пробелами (NaN). Я хотел бы итеративно заполнить недостающие значения значением из предыдущего раза.

Вот игрушечный пример:

import xarray as xr
import numpy as np

# 1. Generate a sample DataArray with missing values
dims = ('y', 'x', 't')
shape = (1000, 1000, 10)
coords = {d: np.arange(s) for d, s in zip(dims, shape)}
mask = np.random.randint(0, 2, shape)
data = np.where(mask, np.random.rand(*shape), np.nan)
da = xr.DataArray(data, dims=dims, coords=coords)

# 2. Write and reload from disk as dask array
da.to_netcdf('_tmp.nc')
da = xr.open_dataarray('_tmp.nc', chunks={'y': 100, 'x': 100, 't': 1})

# 3. Iteratively fill gaps
for t in range(1, len(da['t'])):
    # The following doesn't work with dask arrays
    da[{'t': t}] = da[{'t': t}].fillna(da[{'t': t-1}])

Это будет работать нормально, за исключением того, что массивы dask не поддерживают назначение элементов, и, следовательно, последняя строка не работает. Мой набор данных слишком велик для чтения в память, поэтому вызов .load() не вариант.

Есть ли способ использовать .fillna() таким образом, продолжая использовать ленивую оценку фрагментов, предоставляемых через dask?

Мои настоящие данные составляют около 10000x10000x100 и содержат несколько переменных.


person jhansen    schedule 01.08.2019    source источник


Ответы (1)


На данный момент подобные операции поддерживаются в Xarray лишь частично. В идеале вы можете использовать da.ffill(), но есть некоторые существующие проблемы с реализацией, которые могут не дать вам желаемого результата (чтобы быть точным, xarray в настоящее время не поддерживает заполнение между фрагментами).

Вы можете взглянуть на эту проблему GitHub, чтобы попробовать потенциальное решение: https://github.com/pydata/xarray/issues/2699.

Я призываю вас заняться этим вопросом, если вам кажется, что вы к нему стремитесь.

person jhamman    schedule 01.08.2019
comment
На данный момент кажется, что da.ffill() действительно делает именно то, что мне нужно, и я, вероятно, смогу соответствующим образом адаптировать размеры своих блоков. Если у меня возникнут проблемы, я с радостью вернусь к проблеме GitHub. - person jhansen; 02.08.2019