水文计算的时候常用NSE纳什系数、KGE这两个指标计算模型模拟的准确性,比较喜欢用python来单独对模拟值、观测值进行对比,分享一下简单的代码。
‘./test.txt’ 第一列为观测值,第二列为模拟值
附测试文件
链接:https://pan.baidu.com/s/16lU_gZSk2pLivc2Ut_MnSQ
提取码:la3r
# -*- coding: UTF-8 -*-
from numpy import *
import numpy as np
from math import sqrt
#第一列观测, 第二列模拟
def loaddata(file):
x=[]
y=[]
fileIn=open(file)
for line in fileIn.readlines():
lineArr=line.strip().split()
# print (lineArr)
# 数据集中-9999或者<0的值属于缺测或者异常
if (float(lineArr[0])==-9999 or float(lineArr[0])<0):
continue
x.append(float(lineArr[0]))
# print (x)
y.append(float(lineArr[1]))
return x,y
#计算相关系数r
def R_Square(x,y):
p1=x2=y2=0.0
#计算平均值
x_=mean(x)
y_=mean(y)
#循环读取每个值,计算对应值的累和
for i in range(len(x)):
p1+=(x[i]-x_)*(y[i]-y_)
x2+=(x[i]-x_)**2
y2+=(y[i]-y_)**2
#print(p1,x2,y2)
#计算相关系数
r=p1/((x2** 0.5)*(y2** 0.5))
return r
ob_data,si_data = loaddata('./test.txt')
ob_data = np.array(ob_data)
#print (len(ob_data))
si_data = np.array(si_data)
ob_ave = sum(ob_data)/len(ob_data)
print(sum(ob_data),len(ob_data))
print("ave ",ob_ave)
error = []
ave_error = []
for i in range(len(ob_data)):
if(ob_data[i]<0):
continue
error.append(si_data[i]-ob_data[i])
ave_error.append(ob_data[i]-ob_ave)
squareError = []
absError = []
error = np.array(error)
#print (len(error))
for val in error:
sq=val*val
squareError.append(sq)
absError.append(abs(val))
square_aveError=[]
for val in ave_error:
square_aveError.append(val*val)
Uob = np.mean(ob_data)
Usi = np.mean(si_data)
Stdob = np.std(ob_data)
Stdsi = np.std(si_data)
Alfa = Stdsi/Stdob
Beta = Usi/Uob
r= R_Square(ob_data,si_data)
KGE = 1-sqrt((r-1)**2 + (Alfa-1)**2 + (Beta-1)**2)
print(sum(squareError))
print(sum(square_aveError))
print("RMSE = ", sqrt(sum(squareError)/len(squareError)))
print("NSE = ", 1 - sum(squareError/sum(square_aveError)))
print("MAE = ",sum(absError) / len(absError))
print("KGE = ",KGE)