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

Rasterio读取的NDVI/NDWI栅格数组与QGIS值差异及绘图异常排查

问题描述

我有256张NDVI、NDWI影像,使用以下代码读取:

import os, rasterio
src_mois = (rasterio.open(path))
array_mois = src_mois.read(1)
print(array_mois)

部分影像读取后的数组如下(但QGIS中显示这些影像的值范围为-0.607159至-0.681409):

[[-3.4028235e+38 -3.4028235e+38 -3.4028235e+38 ... -3.4028235e+38
  -3.4028235e+38 -3.4028235e+38]
 [-3.4028235e+38 -3.4028235e+38 -3.4028235e+38 ... -3.4028235e+38
  -3.4028235e+38 -3.4028235e+38]
 [-3.4028235e+38 -3.4028235e+38 -3.4028235e+38 ... -3.4028235e+38
  -3.4028235e+38 -3.4028235e+38]
 ...
 [-3.4028235e+38 -6.2753040e-01 -6.2753040e-01 ... -3.4028235e+38
  -3.4028235e+38 -3.4028235e+38]
 [-3.4028235e+38 -6.1740422e-01 -6.1740422e-01 ... -3.4028235e+38
  -3.4028235e+38 -3.4028235e+38]
 [-3.4028235e+38 -6.5297663e-01 -6.5297663e-01 ... -3.4028235e+38
  -3.4028235e+38 -3.4028235e+38]]

多数影像读取后的数组值与QGIS中显示一致:

[[ 0.34498805  0.4038521   0.45953733 ... -0.00084021 -0.01416653
  -0.01416653]
 [ 0.33337444  0.36398682  0.41986722 ... -0.00888733 -0.02618947
  -0.02618947]
 [ 0.3356307   0.323984    0.34316206 ... -0.0089799  -0.01649707
  -0.01649707]
 ...
 [-0.28778303 -0.312718   -0.312718   ...  0.49572146  0.5651871
   0.5805117 ]
 [-0.2846862  -0.2940772  -0.2940772  ...  0.413783    0.46547
   0.5263974 ]
 [-0.27166343 -0.2786367  -0.2786367  ...  0.3622923   0.37553316
   0.40998626]]

我的目标是对这些影像取平均并使用Seaborn绘图,但直接绘图时程序似乎将-3.4028235e+38识别为-3,导致结果异常。请问这是什么原因?

原因分析与解决办法

1. 异常值本质

你看到的-3.4028235e+38是32位浮点型栅格的标准NoData(无效数据)标记,这个值是该数据类型能表示的最小负数,用来标记影像中无有效观测的区域。

2. QGIS正常显示的原因

QGIS会自动读取栅格元数据里的NoData配置,渲染时会跳过这些无效值,只展示有效数据的范围,所以你能看到正确的-0.607159至-0.681409区间。

3. 绘图异常的原因

Seaborn和底层Matplotlib不会自动识别这个特殊的NoData值,会把它当作正常数据处理。由于这个值远小于NDVI/NDWI的正常范围(-1到1),会极大拉低数据集的统计均值,同时绘图时坐标轴会被这个极小值强制拉伸,正常数据的分布被压缩,看起来像是程序把它识别成-3——这其实是坐标轴刻度自动取整导致的视觉错觉,程序实际处理的是原始的极小值。

4. 解决步骤

要解决这个问题,必须在计算和绘图前屏蔽无效值:

步骤1:读取NoData值

从rasterio数据源中直接获取元数据里的NoData配置:

src_mois = rasterio.open(path)
nodata_val = src_mois.nodata
array_mois = src_mois.read(1)

步骤2:替换为NaN

用numpy将NoData值替换为NaN(Not a Number),后续计算和绘图会自动忽略这类值:

import numpy as np
array_mois[array_mois == nodata_val] = np.nan

步骤3:计算均值与绘图

使用np.nanmean()计算均值(自动忽略NaN),然后过滤NaN值再绘图:

import seaborn as sns
import matplotlib.pyplot as plt

# 假设所有处理后的影像数组存入all_arrays列表
mean_array = np.nanmean(all_arrays, axis=0)
# 展平数组并过滤NaN
flat_mean = mean_array.flatten()
flat_mean = flat_mean[~np.isnan(flat_mean)]

# 示例:绘制直方图
sns.histplot(flat_mean)
plt.title("Mean NDVI/NDWI Distribution")
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 07:37:15