将每日时间序列汇总为具有 NaN 值阈值的每月时间序列

Sum a daily time series into a monthly time series with a NaN value threshold

我有一个从1979年1月1日到2005年12月31日的3D时间序列数据矩阵,矩阵目前是9862x360x720(每日降雨量x 0.5°纬度x 0.5°经度)。我想将每天的降雨量汇总为每月的降雨量(总共 324 个月),同时还设置一个用于求和 NaN 值的阈值。

换句话说,如果特定 lat/lon 网格单元格的每日 NaN 值超过 10 个,我想将每月求和的单元格标记为 NaN。如果网格单元格的每日 NaN 值少于 10 个,我想对剩余的非 NaN 每日值求和并将其用作每月值。

我成功使用了 xarray 库的 "resample" 函数,但我想不出一种方法来设置 NaN 值的阈值。我读过的所有内容都说使用 sum 或 nansum 函数,但我找不到通过这些函数中的任何一个来设置 NaN 阈值的方法。此时我对任何方法(xarray 或其他)持开放态度。

import netCDF4
import numpy as np
import xarray as xr
import pandas as pd

f = netCDF4.Dataset("daily_data", 'r')

daily_dataset = xr.Dataset({'precipitation': (['time', 'lat', 'lon'],  f['precipitation'][:, :, :])},
             coords={'lat': (f['lat'][:]), 'lon': (f['lon'][:]), 'time': pd.date_range('1979-01-01', periods=9862)})

monthly_dataset = daily_dataset['precipitation'].resample('M', dim='time', how='sum', skipna=False)

我可以使用上面的代码将每日数据汇总到每月,但无法设置 NaN 阈值。每日数据当前存储在 NetCDF 文件中。

我相信这可以满足您的需求:

NaN = float("nan") # Make a constant for NaN

def sum_nan_threshold(iterable, *, nan_threshold=10):
    if sum(x == NaN for x in iterable) >= nan_threshold: # Are there more NaNs then threshold?
        return NaN
    else:
        return sum(x for x in iterable if x != NaN) # Else sum up if not equal to NaN