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

使用Scipy.ndimage旋转含np.nan的数组出现值异常问题

问题描述

我有一个来自.tif格式LiDAR表面的高程数组,示例数组如下:

from scipy.ndimage import rotate
import numpy as np
test_surface_nan =  [[np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
                     [np.nan, np.nan, np.nan,   1,    np.nan, np.nan, np.nan],
                     [np.nan, np.nan,   1,      2,      1,    np.nan, np.nan],
                     [np.nan,   1,      2,      3,      2,      1,    np.nan],
                     [np.nan, np.nan,   1,      2,      1,    np.nan, np.nan],
                     [np.nan, np.nan, np.nan,   1,    np.nan, np.nan, np.nan],
                     [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan]]

尝试执行以下代码将数组旋转45度,使有效值起始于第1行:

test_surface_array_nan = np.array(test_surface_nan)
test_surface_array_nan_rotated = rotate(test_surface_array_nan,45,reshape=True)

但得到的结果中,原大于0的有效值变为np.nan,原np.nan元素变为0,与预期结果不符:

maybe_test_surface_nan =  [  [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
                             [np.nan,    1,   np.nan,   1,    np.nan,    1,   np.nan],
                             [np.nan, np.nan,   2,    np.nan,   2,    np.nan, np.nan],
                             [np.nan,    1,   np.nan,   3,    np.nan,    1,   np.nan],
                             [np.nan, np.nan,   2,    np.nan,   2,    np.nan, np.nan],
                             [np.nan,    1, np.nan,     1,    np.nan,    1,   np.nan],
                             [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan]]
问题原因
  • scipy.ndimage.rotate默认使用三阶样条插值(order=3),当数组包含np.nan时,插值计算会因NaN的传播特性,将原本的有效值也转换成NaN。
  • 默认填充模式为mode='reflect',但NaN的存在会导致填充逻辑失效,旋转后的空白区域最终被0替代,出现原NaN区域变成0的情况。
解决办法

调整rotate函数的参数,避免NaN传播并指定正确的填充值:

  1. 使用最近邻插值(order=0),阻止插值过程中NaN破坏有效值;
  2. 设置填充模式为mode='constant',并指定填充值为np.nan,确保空白区域用NaN填充而非0;
  3. 保留reshape=True适配旋转后的数组尺寸。

修改后的代码示例:

from scipy.ndimage import rotate
import numpy as np

test_surface_nan =  [[np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
                     [np.nan, np.nan, np.nan,   1,    np.nan, np.nan, np.nan],
                     [np.nan, np.nan,   1,      2,      1,    np.nan, np.nan],
                     [np.nan,   1,      2,      3,      2,      1,    np.nan],
                     [np.nan, np.nan,   1,      2,      1,    np.nan, np.nan],
                     [np.nan, np.nan, np.nan,   1,    np.nan, np.nan, np.nan],
                     [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan]]

test_surface_array_nan = np.array(test_surface_nan)
# 调整参数后的旋转代码
test_surface_array_nan_rotated = rotate(
    test_surface_array_nan,
    45,
    reshape=True,
    order=0,  # 最近邻插值
    mode='constant',
    cval=np.nan  # 空白区域填充NaN
)

print(test_surface_array_nan_rotated)

注:旋转后数组尺寸会变为10x10(原7x7旋转45度的最小外接矩形),若需保持7x7尺寸可去掉reshape=True,但会裁剪部分内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 19:20:21