xarray.DataArray.groupby的一次使用记录

项目场景:

一个日数据序列场,还有一个多年月平均场,把日数据减去多年月平均场得到日数据异常序列场


问题描述

由于每个月的天数不同,故难以利用广播机制完成任务。开始想到一个笨方法就是把月平均场利用每个月的天数将月平均场还原成日数据序列场一样的长度然后直接相减。在思索之后,限于编程能力的不足开始寻找新的方法。两数组维度如下:
在这里插入图片描述
在这里插入图片描述


解决方案:

在不断查找后发现xarray.DataArray.groupby用法,以前没发现这个,在去研究后发现这个函数在有些问题背景下真的很方便。简单描述这个函数就是讲xarray.DataArray数组类型根据需求分成不同的类处理,一看到这个就与我的问题契合了。我只需要将日数据序列以月分类后就可以直接与月平均序列场相减了,十分方便。原本很复杂的一个问题只需要一行代码就可完成。
核心代码如下:

sst_day.groupby('time.month') - sst_day_sec.groupby('time.month').mean(dim="time")

此处sst_day_sec并非已经处理好的月平均数据场,这里是挑选的30年的时序数据作为气候态。要求解多年月平均在这个函数下就变得简单起来,只需要将其月分类,再根据时间维度做平均就可以了。
关于xarray.DataArray.groupby的其他用法还很丰富,在将来有需求的时候继续探索。

import pandas as pd import xarray as xr from cnmaps import get_adm_maps, clip_contours_by_map, draw_maps import matplotlib.pyplot as plt import cartopy.crs as ccrs import cartopy.feature as cfeature from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER import matplotlib.colors as mcolors import matplotlib.patches as mpatches # 读取数据 ds = xr.open_dataset("Z_RADA_C_BABJ_20250302000942_P_DOR_YN_FHCR_SC_1KM_20250302_000000.nc") print(ds) sm_data = ds["CREF"] # 根据实际变量名调整 lat = ds["Lat"] lon = ds["Lon"] time_coverage=ds["time"] minu_group = ds.groupby("time.minute") for group_name, group_ds in minu_group: # 当第一个循环结束时,停止遍历 minu_group print(group_name) break group_ds list_group = list(minu_group) list_group def time_mean(a): return a.mean(dim="time") monthsst = minu_group.map(time_mean) monthsst # 常量 startLon = 98 endLon = 100.15 startLat = 24 endLat = 26 # 使用cnmaps获取保山市边界 baoshan = get_adm_maps(city="保山市", level='市') # level可选'市','县','乡' # 地图白化 fig = plt.figure(figsize=(16, 8)) ax = fig.add_subplot(111, projection=ccrs.PlateCarree()) ax.set_extent([startLon, endLon, startLat, endLat], crs=ccrs.PlateCarree()) colorlevel=[-100,-50,-25,0,25,50,100,]#气温等级 colordict=['#ff0000', '#ff9628','#ffff00','#afff00','#00beff','#800040']#颜色列表 rain_map=mcolors.ListedColormap(colordict)#产生颜色映射 norm=mcolors.BoundaryNorm(colorlevel,rain_map.N)#生成索引 # 绘制土壤湿度数据 cs1= ax.contourf(lon,lat,monthsst,levels=colorlevel,cmap=rain_map,norm=norm,transform=ccrs.PlateCarree(),extend='both') labels=['<-50','-50~-25','-25~0', '0~25','25~50','>90'] #labels=['重旱','中旱', '轻旱','无旱','渍涝'] myLegend=[mpatches.Rectangle((0, 0), 1, 2, facecolor=c) for c in colordict] ax.legend(myLegend, labels,fontsize=9,frameon=False,title='图例',ncol=1, loc='lower left', bbox_to_anchor=(0, -0.01), fancybox=True) # 画县 map_with_country = get_adm_maps(province='云南省', city="保山市", level="县") print(map_with_country) draw_maps(map_with_country, linewidth=0.8, color='#5f5f5f') # 县区 stationIds = pd.read_csv("保山市县区.csv", encoding="gbk") name = stationIds['Sta'] lon = stationIds['Lon'] lat = stationIds['Lat'] lonlat = zip(lon, lat) mapname = dict(zip(name, lonlat)) for key, value in mapname.items(): print("==================", value[0], value[1]) ax.scatter(value[0], value[1], marker='.', s=10, color="k", zorder=3) ax.text(value[0] - 0.04, value[1] + 0.01, key, fontsize=10, color="k") # 添加网格和标注 gl = ax.gridlines(draw_labels=True,linewidth=0.5, color='gray', alpha=0)#网格线颜色、宽度、 gl.xformatter = LONGITUDE_FORMATTER gl.yformatter = LATITUDE_FORMATTER gl.top_labels = False gl.right_labels = False #装饰 plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定中文字体(如黑体) plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题 ax.set_title("保山市3月16日土壤干旱分布图", loc="center", fontsize=14,pad=10) #def add_department_watermark(fig,text): ax.text(0.98, 0.05, "制作单位:保山市气象科技服务中心\n",ha='right', va='bottom', fontsize=8, color='black',transform=ax.transAxes) #fig.text(0.98, 0.02, "制作单位:保山市气象科技服务中心\n",ha='right', va='bottom', fontsize=8, color='black') #fig.text(0.95, 0.03,"Produced by: Energy Analytics Dept | Confidential",ha='right',fontsize=9,color='#666666',alpha=0.7) #切图 bs_map_outline = get_adm_maps(province='云南省',city="保山市", record='first', only_polygon=True) clip_contours_by_map(cs1, bs_map_outline) #map_polygon=get_adm_maps(province='云南省',city="保山市", record='first', only_polygon=True) #clip_contours_by_map(bs, bs_map_outline) #map_polygon = get_adm_maps(province='云南省',city="保山市",record='first', only_polygon=True) plt.savefig('baoshan_soil_moisture_cnmap.png', dpi=800, bbox_inches='tight') plt.show() print("工作完成.") 此代码显示TypeError: cannot directly convert an xarray.Dataset into a numpy array. Instead, create an xarray.DataArray first, either with indexing on the Dataset or by invoking the `to_array()` method.请问怎么解决
03-21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值