Python中使用xarray计算2D时间序列交叉相关及多滞后相关性的方法
xarray计算NINO指数与降水滞后交叉相关方案
假设你已完成基础数据预处理:降水数据为月尺度,维度为[time, lat, lon];JJA NINO指数维度为[time],二者时间坐标均为标准datetime格式,时间范围覆盖所需的最大滞后区间。
核心实现步骤
1. 时间对齐
先提取两个序列的重叠时间区间,避免时间错位:
import xarray as xr import numpy as np from scipy.stats import pearsonr # 对齐时间,取二者重叠的时间段 nino_aligned, precip_aligned = xr.align(nino_jja, precip, join="inner")
2. 构造不同滞后的序列
我们需要计算降水滞后0/3/6/9/12个月的场景,这里的滞后定义为:NINO在t时刻的取值对应降水在t+k时刻的取值:
lags = [0, 3, 6, 9, 12] # 批量构造不同滞后的降水与对应匹配的NINO序列 precip_lagged_list = [] nino_matched_list = [] for k in lags: if k == 0: # 无滞后直接取全部对齐数据 precip_lagged = precip_aligned nino_matched = nino_aligned else: # 降水滞后k个月:降水从第k个时间点开始取,NINO取到倒数第k个时间点 precip_lagged = precip_aligned.isel(time=slice(k, None)) nino_matched = nino_aligned.isel(time=slice(None, -k)) # 新增lag维度,方便后续合并 precip_lagged_list.append(precip_lagged.expand_dims(lag=[k])) nino_matched_list.append(nino_matched.expand_dims(lag=[k])) # 合并所有滞后序列 precip_all_lags = xr.concat(precip_lagged_list, dim="lag") nino_all_lags = xr.concat(nino_matched_list, dim="lag")
3. 计算相关系数
直接调用xarray内置的corr方法在time维度计算皮尔逊相关,结果维度为[lag, lat, lon]:
# 仅计算相关系数 corr_result = xr.corr(nino_all_lags, precip_all_lags, dim="time")
如果需要同时输出相关系数对应的显著性p值,使用apply_ufunc对接scipy的pearsonr实现:
def calc_pearsonr(x, y): # 过滤缺测值 valid_mask = ~np.isnan(x) & ~np.isnan(y) if valid_mask.sum() < 3: # 有效样本量不足3的话返回空 return np.nan, np.nan r, p = pearsonr(x[valid_mask], y[valid_mask]) return r, p corr_coef, p_value = xr.apply_ufunc( calc_pearsonr, nino_all_lags, precip_all_lags, input_core_dims=[["time"], ["time"]], output_core_dims=[[], []], vectorize=True, dask="parallelized", # 若使用dask数组可开启并行加速 output_dtypes=[np.float64, np.float64] )
注意事项
- 如果你的JJA NINO是年尺度数据(每年仅1个值对应6-8月平均),需要先把降水处理为对应滞后的季节/月平均后按年匹配,不要直接用月降水匹配年尺度NINO
- 计算前建议对两个时间序列做去趋势处理,避免长期趋势干扰相关结果,可直接调用
xarray.detrend方法实现 - 若数据存在较多缺测,建议先做缺测插值或者设置最小有效样本量阈值,过滤掉结果中不可靠的格点
内容的提问来源于stack exchange,提问作者pattylyn
相关产品推荐
相关产品推荐

