Если вы хотите получить среднее число значений NaN, вам поможет что-то такое простое, как da.isnull().mean(dim='time')
. Но получить среднюю и максимальную длину непрерывных блоков NaNs - более сложный алгоритмический вопрос, чем простой процедурный вопрос xarray.
Я уверен, что есть много способов сделать это, но тот, который я придумал, был таким:
Сначала создайте массив такой же формы, что и ваши данные, который просто увеличивается по временному измерению:
In [10]: arange = xr.ones_like(da) * np.arange(len(da.time))
В данных игрушки, которые я сделал для этого, временные ряды каждой ячейки выглядят так:
In [11]: arange.isel(lat=0, lon=0).plot()
Затем создайте аналогичный массив, но с периодами, которые содержат константу для каждого блока NaN:
In [12]: cumulative_nans = (arange.where(da.notnull()).ffill(dim='time')).fillna(0)
В каждой ячейке этого массива есть ступени лестницы для каждого блока NaN:
In [13]: cumulative_nans.isel(lat=0, lon=0).plot()
Теперь вы можете вычесть эти два, чтобы получить массив, в котором значение в каждой ячейке является счетчиком с совокупным числом NaN в этом блоке:
In [14]: time_series_of_cumulative_nan_blocks = (arange - cumulative_nans)
В каждой ячейке:
In [15]: time_series_of_cumulative_nan_blocks.isel(lat=0, lon=0).plot()
Вы можете легко рассчитать максимальное значение для этого:
In [16]: max_nan_duration = time_series_of_cumulative_nan_blocks.max(dim='time')
Среднее значение сложнее. Мы можем использовать переход от одного временного шага к следующему, чтобы отфильтровать данные, чтобы включить только точки, где отклоняется следующая ячейка, например, где у нас есть пик:
In [17]: nan_block_length_peaks_only = (
time_series_of_cumulative_nan_blocks
.where(
time_series_of_cumulative_nan_blocks
.diff(dim='time', label='lower')
< 0)
В каждой ячейке третье число ограничено набором точек:
In [18]: nan_block_length_peaks_only.isel(lat=0, lon=0).plot(marker='.')
Это значение может быть усреднено, чтобы найти среднюю продолжительность:
In [19]: mean_nan_duration = nan_block_length_peaks_only.mean(dim='time')
Это должно иметь значительные преимущества в производительности по сравнению с циклическим просмотром каждой ячейки и периода времени в наборе данных, главным образом потому, что оно основано на скомпилированных векторизованных функциях xarray, а не на циклах python. Это вычисление также может быть выполнено для всего набора данных с использованием dask , что может привести к дальнейшему увеличению, в зависимости от ваших настроек.