You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将xarray DataArray中存在于指定列表的值标记为1,其余为0?

解决思路:生成匹配指定列表的xarray二进制数组

问题背景

我有一个非零数值列表blob_numbers_126_list,需要与三维(time,lat,lon)的xarray DataArray blobs_126对比,生成二进制数组——值在列表中则标记为1,否则为0。

列表生成代码:

blob_numbers_126 = blobs_126.where(icemask_126_regrid[30,:,:] == 1).data.flatten()
blob_numbers_126 = blob_numbers_126[~np.isnan(blob_numbers_126)]
blob_numbers_126_list = list(set(blob_numbers_126[blob_numbers_126!=0]))

当前使用xr.where()的代码得到全1数组,不符合预期:

blobs_126_source = blobs_126.where(blobs_126[:,:,:].data == any(np.array(blob_numbers_126_list)),1,0)

错误原因

  • any(np.array(blob_numbers_126_list))会将整个列表转换为单个布尔值(只要列表非空就返回True),导致条件变为blobs_126.data == True,所有非零数值都会匹配该条件,最终生成全1数组。
  • 直接操作.data绕过了xarray的维度对齐机制,不是推荐的用法。

正确解决方法

方法1:使用xarray内置isin()方法(推荐)

xarray的DataArray自带isin()方法,可直接逐元素检查是否在目标列表中,返回布尔掩码后转换为1/0数组:

# 生成布尔掩码
match_mask = blobs_126.isin(blob_numbers_126_list)
# 转换为二进制数组,保留原维度和坐标
blobs_126_source = match_mask.astype(int)

# 也可以用xr.where实现相同效果
blobs_126_source = xr.where(match_mask, 1, 0)

方法2:结合numpy的in1d()操作

如果习惯用numpy处理,可先展平数组检查匹配,再重构回原三维结构:

# 展平数组并检查每个元素是否在列表中
flat_match = np.in1d(blobs_126.data.flatten(), blob_numbers_126_list)
# 重构回原DataArray的形状
match_mask = flat_match.reshape(blobs_126.shape)
# 转换为带坐标的DataArray
blobs_126_source = xr.DataArray(match_mask.astype(int), coords=blobs_126.coords, dims=blobs_126.dims)

额外优化:用集合提升匹配效率

由于你的列表是通过set生成的,直接使用集合做匹配能大幅提升效率(尤其当元素数量较多时):

# 直接生成集合而非列表
blob_numbers_126_set = set(blob_numbers_126[blob_numbers_126!=0])
# 后续用isin(blob_numbers_126_set)即可,xarray会自动兼容集合类型

内容的提问来源于stack exchange,提问作者jpleis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 06:53:00