一、问题
我今天使用代码求ERA5的每年栅格平均值,但是我发现结果明显偏高,在我反复更换了GDAL等代码库时发现结果还是偏高,以下是我检验出结果偏高的原因:
1. 我算的是年anomaly结果按理说会在0值线上下波动。
2. 我习惯使用arcgis进行计算进行验证,结果显示arcgis是正确的。
二、原因
在我寻找结果的过程中我发现了一个问题,那就是栅格的nodata值(尤其是一些别人的数据产品)似乎和代码处理后我自己赋予的nodata值(实际上是背景值)不是一回事,之前我经常使用value > 0就能正确计算是因为这两个值一般情况都是小于0(例如NDVI或降水等栅格数据),但是这次情况很特殊,nodata值竟然是255,这就导致我一直无法正确计算整个栅格的平均值,有趣的是arcgis或者说arcpy调用工具是可以忽视所有nodata值的。
三、解决方案
所以大家在进行代码运算栅格平均值时,一定要检查栅格自身的nodata值,并在代码中忽略它。
图1 可以看到Nodata值为255(Arcgis pro 栅格属性)
附上一段Python代码供参考:
#中国所有区域降水异常
import os
import re
import numpy as np
import matplotlib.pyplot as plt
import rasterio
# 文件夹路径
folder_path = 'J:\\GrasslandCarbon2000-2020\\Cliamte_Analysis\\PreAno'
# 获取文件夹中的所有文件
files = os.listdir(folder_path)
# 过滤出.tif文件并按照年份排序
raster_files = sorted([f for f in files if f.endswith('.tif') and f.startswith('pre_')], key=lambda x: int(re.findall(r'\d+', x)[0]))
# 初始化列表以存储平均值
average_values = []
# 遍历每个栅格文件
for raster_file in raster_files:
# 打印文件名
print(raster_file)
# 打开文件
with rasterio.open(os.path.join(folder_path, raster_file)) as dataset:
# 读取数据
data = dataset.read(1)
# 忽略arcgis中看到的nodata值,本例为255
valid_data = data[data != 255]
average_value = valid_data.mean()
average_values.append(average_value)
# 提取年份
years = [int(re.findall(r'\d+', f)[0]) for f in raster_files]
# 绘制折线图
plt.plot(years, average_values, marker='o')
plt.xlabel('Year')
plt.ylabel('PreAno')
plt.title('Average PreAno over Years')
plt.grid(True)
plt.show()