xarray对等尺寸数组执行逐元素与运算后结果形状异常
问题原因
这是xarray的有意设计行为,标签对齐算术是xarray的核心特性之一:所有xarray对象之间的运算默认会基于维度的坐标标签自动对齐,而非按数组元素的位置对齐。
你遇到的现象原因很明确:
- 你对
ice_concentration最后一维做的两次切片1:-1和:-2,得到的两个数组虽然数值形状都是(947,737),但它们最后一维的坐标标签集合并不完全重合:1:-1的最后一维坐标是原数组下标1到倒数第2对应的标签,:-2的最后一维坐标是原数组下标0到倒数第3对应的标签,两者只有736个共同的坐标标签。 - 做
&运算时xarray会自动对两个数组的坐标做内连接,仅保留两边都存在的坐标对应的元素,因此运算结果最后一维长度变成736。也正是因为坐标对齐后,你原本要对比的邻域元素被匹配到了相同坐标的自身元素,才会出现np.sum(mask)返回0的问题。
当你调用.values转成numpy数组后,numpy数组没有坐标标签属性,只会按元素的位置顺序逐位运算,自然就能得到你预期的邻域对比结果。
推荐解决方案
如果不想转numpy数组,想要保留xarray的坐标特性做邻域运算,可以使用xarray原生的shift方法偏移坐标,不需要手动切片对齐:
threshold = 0.7 # 沿最后一维向左偏移1个单位,坐标保持和原数组对齐 left_neighbour = d.ice_concentration[0].shift(dim=-1, n=1) mask = (d.ice_concentration[0] < threshold) & (left_neighbour > threshold) # 去掉边缘的空值 mask = mask[1:-1, 1:-1]
如果就是想要按数组位置运算不考虑坐标,也可以在运算前重置维度的坐标为位置索引:
arr1 = d.ice_concentration[0,1:-1,1:-1].assign_coords({'x': range(737), 'y': range(947)}) arr2 = d.ice_concentration[0,1:-1,:-2].assign_coords({'x': range(737), 'y': range(947)}) mask = arr1 < threshold & arr2 > threshold
内容的提问来源于stack exchange,提问作者Tor
相关产品推荐
相关产品推荐

