如何在xarray中按自定义时间范围分组?

2024-10-01 17:33:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个带有日期、x和y坐标DIM的数据数组

date: 265, y: 1458, x: 1159

在35年的时间里,每年大约有10个阵列带有日期和x、y阴影

我想按一个自定义的年度季节分组,以便在该自定义的年度季节(可能是每年的10月到4月)内集成每个光栅的值。xarray文档显示,我可以执行以下操作:

arr.groupby("date.season")

导致

DataArrayGroupBy, grouped over 'season' 
4 groups with labels 'DJF', 'JJA', 'MAM', 'SON'.

但在整个35年的记录中,这是按季节分组的,我无法控制用于分组的开始和结束月份

同样,这并不能完全满足我的要求:

all_eeflux_arr.groupby("date.year")
DataArrayGroupBy, grouped over 'year' 
36 groups with labels 1985, 1986, 1987, ..., 2019, 2020.

每年的开始和结束日期自动为1月/12月

我真的希望能够按任意时间段分组,开始时间和结束时间以一年中的某一天为单位。

如果这个分组也可以丢弃不在分组窗口内的日期,那就更好了,因为我可能想按一个不跨越所有月份的日期范围进行分组

DataArray.resample方法似乎能够为年初选择一个自定义偏移量(see this SO post),但我不知道如何使用groupby访问它。我不能使用重采样,因为它不返回DataArray,我需要对每个组DataArray调用.integratexarray方法(跨越date dim,以获得自定义的年度总计)

要复制的数据(2Gb,但可以在子集上进行测试): https://ucsb.box.com/s/zhjxkqje18m61rivv1reig2ixiigohk0

要复制的代码

import rioxarray as rio
import xarray as xr
import numpy as np
from pathlib import Path
from datetime import datetime

all_scenes_f_et = Path('/home/serdp/rhone/rhone-ecostress/rasters/eeflux/PDR')

all_pdr_et_paths = list(all_scenes_f_et.glob("*.tif"))

def eeflux_path_date(path):
    year, month, day, _ = path.name.split("_")
    return datetime(int(year), int(month), int(day))

def open_eeflux(path, da_for_match):
    data_array = rio.open_rasterio(path) #chunks makes i lazyily executed
    data_array.rio.reproject_match(da_for_match)
    data_array = data_array.sel(band=1).drop("band") # gets rid of old coordinate dimension since we need bands to have unique coord ids
    data_array["date"] = eeflux_path_date(path) # makes a new coordinate
    return data_array.expand_dims({"date":1}) # makes this coordinate a dimension

da_for_match = rio.open_rasterio(all_pdr_et_paths[0])
daily_eeflux_arrs = [open_eeflux(path, da_for_match) for path in all_pdr_et_paths]
all_eeflux_arr = xr.concat(daily_eeflux_arrs, dim="date")

all_eeflux_arr = all_eeflux_arr.sortby("date")

### not sure what should go here
all_eeflux_arr.groupby(????????).integrate(dim="date", datetime_unit="D")

非常感谢您的建议


Tags: pathimportfordatadatetimedatematchall
1条回答
网友
1楼 · 发布于 2024-10-01 17:33:37

最后,我编写了一个运行良好的函数。由于我的数据集并没有那么大,所以在遍历每个组的for循环中运行集成不会花费很长时间

def group_by_custom_doy(all_eeflux_arr, doy_start, doy_end):
    ey = max(all_eeflux_arr['date.year'].values)
    sy = min(all_eeflux_arr['date.year'].values)
    start_years = range(sy,ey)
    end_years = range(sy+1, ey+1)
    start_end_years = list(zip(start_year,end_year))
    water_year_arrs = []
    for water_year in start_end_years:
        start_mask = ((all_eeflux_arr['date.dayofyear'].values > doy_start) & (all_eeflux_arr['date.year'].values == water_year[0]))
        end_mask = ((all_eeflux_arr['date.dayofyear'].values < doy_end) & (all_eeflux_arr['date.year'].values == water_year[1]))
        water_year_arrs.append(all_eeflux_arr[start_mask | end_mask])
    return water_year_arrs

water_year_arrs = group_by_custom_doy(all_eeflux_arr, 125, 300)

相关问题 更多 >

    热门问题