1 什么是变异系数
变异系数是衡量观测值与单位均 值 离散程度 的一 个统计量,标准差与均值的比值为变异系数 。其变异系数越大,说明NDVI/EVI/NPP/NEP/GPP时间序列数据波动比较大 ,时序不稳定; 反之, 说明指标时间序列数据波动比较小,时序稳定。
公式如下:

2 代码实现变异系数
python
import numpy as np
import os
from osgeo import gdal
def read_tif(filepath):
dataset = gdal.Open(filepath)
col = dataset.RasterXSize # 图像长度
row = dataset.RasterYSize # 图像宽度
geotrans = dataset.GetGeoTransform() # 读取仿射变换
proj = dataset.GetProjection() # 读取投影
data = dataset.ReadAsArray() # 转为numpy格式
data = data.astype(np.float32)
no_data_value = data[0][0] # 设定NoData值
data[data == no_data_value] = np.nan # 将NoData转换为NaN
return col, row, geotrans, proj, data
def save_tif(data, reference_file, output_file):
ds = gdal.Open(reference_file)
shape = data.shape
driver = gdal.GetDriverByName("GTiff")
dataset = driver.Create(output_file, shape[1], shape[0], 1, gdal.GDT_Float32) # 保存的数据类型
dataset.SetGeoTransform(ds.GetGeoTransform())
dataset.SetProjection(ds.GetProjection())
dataset.GetRasterBand(1).WriteArray(data)
dataset.FlushCache()
def get_tif_list(directory):
"""
获取目录下所有TIF文件的完整路径
"""
return [os.path.join(directory, f) for f in os.listdir(directory) if f.endswith('.tif')]
def coefficient_of_variation(data): # 变异系数
mean = np.mean(data) # 计算平均值
std = np.std(data, ddof=0) # 计算标准差
cv = std/mean
return cv
if __name__ == '__main__':
# 输入文件夹路径
input_directory = r"E:\AAWORK\02-处理\ndvi-86-24"
output_directory = r"E:\AAWORK\03-结果\01时空分析\cv"
# 读取文件列表
file_list = get_tif_list(input_directory)
# 读取第一个文件获取基本信息(列、行、仿射变换、投影)
col, row, geotrans, proj, _ = read_tif(file_list[0])
# 预分配结果数组
cv_data = np.zeros((row, col), dtype=np.float32)
# 将所有 TIFF 文件的数据堆叠为一个三维数组 (时间, 行, 列)
tif_stack = np.array([read_tif(f)[4] for f in file_list])
# 遍历每个像素
for i in range(row):
print(f"Processing row {i+1}/{row}...")
for j in range(col):
pixel_values = tif_stack[:, i, j] # 取出所有时间点的该像素值
if not np.any(np.isnan(pixel_values)): # 过滤掉包含NaN的像素
CV_value = coefficient_of_variation(pixel_values) # 变异系数计算
cv_data[i, j] = CV_value
# 输出文件路径
save_tif(cv_data, file_list[0], os.path.join(output_directory, 'cv.tif'))
print("Processing completed!")
3 变异系数分等级
分类参考某论文

python
import numpy as np
from osgeo import gdal
def read_tif(filepath):
dataset = gdal.Open(filepath)
col = dataset.RasterXSize#图像长度
row = dataset.RasterYSize#图像宽度
geotrans = dataset.GetGeoTransform()#读取仿射变换
proj = dataset.GetProjection()#读取投影
data = dataset.ReadAsArray()#转为numpy格式
data = data.astype(np.float32)
a = data[0][0]
data[data == a] = np.nan
return [col, row, geotrans, proj, data]
def save_tif(data, file, output):
ds = gdal.Open(file)
shape = data.shape
driver = gdal.GetDriverByName("GTiff")
dataset = driver.Create(output, shape[1], shape[0], 1, gdal.GDT_Int16)#保存的数据类型
dataset.SetGeoTransform(ds.GetGeoTransform())
dataset.SetProjection(ds.GetProjection())
dataset.GetRasterBand(1).WriteArray(data)
if __name__ == '__main__':
# 调用
cv_path = r"E:\AAWORK\03-结果\01时空分析\cv\cv01.tif"
output_path = r"E:\AAWORK\03-结果\01时空分析\cv\cv_level.tif"
col, row, geotrans, proj, cv_data = read_tif(cv_path)
classified = np.zeros_like(cv_data, dtype=np.int16)
classified[(cv_data > 0) & (cv_data < 0.05)] = 1
classified[(cv_data >= 0.05) & (cv_data < 0.1)] = 2
classified[(cv_data >= 0.1) & (cv_data < 0.15)] = 3
classified[(cv_data >= 0.15) & (cv_data < 0.2)] = 4
classified[(cv_data >= 0.2)] = 5
save_tif(classified,cv_path,output_path)