python mk趋势检验的实现
时间:2023-12-16 01:07:02
网上查了很久MK大部分突变检验代码都是基于matlab实现。因为我不熟悉。matlab,于是将matlab代码转换成python最终调试正确可操作的代码。
代码
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
plt.rcParams['font.family'] = ['MicroSoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
df = pd.read_excel(r'D:\py\data.xls')
# 获取数据
x = df['year']
y = df['data']
n = len(y)
# 正序计算
# 定义累计量序列Sk,长度n,初始值为0
Sk = np.zeros(n)
UFk = np.zeros(n)
# 定义Sk序列元素s
s = 0
for i in range(1, n):
for j in range(0,i):
if y.iloc[i] > y.iloc[j]:
s = 1
Sk[i] = s
E = (i 1)*(i/4)
Var = (i 1)*i*(2*(i 1) 5)/72
UFk[i] = (Sk[i] - E)/np.sqrt(Var)
# 逆序计算
# 逆累计量序列的定义Sk2
# 逆统计量序列的定义Sk2
y2 = np.zeros(n)
Sk2 = np.zeros(n)
UBk = np.zeros(n)
s = 0
y2 = y[::-1]
for i in range(1, n):
for j in range(0,i):
if y2.iloc[i] > y2.iloc[j]:
s = 1
Sk2[i] = s
E = (i 1)*(i/4)
Var = (i 1)*i*(2*(i 1) 5)/72
UBk[i] = -(Sk2[i] - E)/np.sqrt(Var)
UBk2 = UBk[::-1]
# 画图
plt.figure(figsize=(7, 6), dpi=350)
plt.plot(range(18),UFk, label='UF', color='black',marker='s')
plt.plot(range(18), UBk2, label='UB',color='black', linestyle='--', marker='o')
plt.ylabel('Mann-Kendall检验值')
plt.xlabel('年份 Year')
# 添加辅助线
x_lim = plt.xlim()
# 添加显著的水平线和y=0
plt.plot(x_lim,[-1.96,-1.96],':',color='black',label=5%明显水平
plt.plot(x_lim, color='black')
plt.plot(x_lim,[1.96,1.color='black')
plt.xticks(range(18), x.tolist(), rotation=45)
# plt.legend(loc='upper right', bbox_to_anchor=(0.9,0.95),ncol=3,fancybox=True)
# 设置图例位置,调整左右位置的第一个参数,调整上下位置的第二个参数
plt.legend(bbox_to_anchor=(0.75,0.07), facecolor='w',frameon=False)
# 添加文本注释
plt.text(0,-1.六、检验突变点)
plt.savefig("../IMG/MK检验.png")
plt.show()
结果
标签:plt,Sk2,python,检验,color,range,black,mk,np
来源: https://blog.csdn.net/qq_41898946/article/details/113823174