Python编写M-K突变检验

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams[‘font.sans-serif’] = [‘SimHei’] #用来正常显示中文标签
plt.rcParams[‘axes.unicode_minus’] = False #用来正常显示负号

input_data = pd.read_csv(r"D:\PycharmProjects\shuiziyuan\M-K检验\runoff.csv") # 输入文件的绝对路径,数据样式如下图
Python编写M-K突变检验_第1张图片

print(input_data.head())
print(len(input_data))

正序列计算

Sk_list = [0] # 定义累计量序列Sk,初始值=0
UFk_list = [0] # 定义统计量UFk,初始值 =0
Sk = 0 # 定义Sk序列元素s,初始值 =0
Exp_Sk_value_list = [0] # 均值
Var_Sk_value_list = [0] # 方差

i从1开始,因为根据统计量UFk公式,i=0时,Sk(0)、E(0)、Var(0)均为0

此时UFk无意义,因此公式中,令UFk(0)=0

for i in range(1, len(input_data)):
for j in range(i):
if input_data[“runoff”][i] > input_data[“runoff”][j]:
Sk = Sk + 1
else:
Sk = Sk + 0
Sk_list.append(Sk)
Exp_Sk = (i+1)(i+2)/4
Exp_Sk_value_list.append(Exp_Sk)
# print(Exp_Sk_value_list)
Var_Sk = (i+1)i(2
(i+1)+5)/72
Var_Sk_value_list.append(Var_Sk)

UFk = (Sk_list[i]-Exp_Sk_value_list[i])/np.sqrt(Var_Sk_value_list[i])
UFk_list.append(UFk)

print(Sk_list)

print(UFk_list)

print(Exp_Sk_value_list)

print(Var_Sk_value_list)

print("---------------正向运算结束---------------")

逆序列计算

Sk2_list = [0] # 定义逆序累积量序列Sk2,长度与inputdata一致,初始值=0
UBk_list = [0] # 定义逆序累积量序列UBk,长度与原始数据一致,初始值=0
UBk2_list = [0]
Sk2 = 0 # 初始值为0
Exp_Sk2_value_list = [0] # 均值
Var_Sk2_value_list = [0] # 方差
input_data_T = list(reversed(input_data[“runoff”])) # 时间序列逆转样本

i从1开始,因为根据统计量UBk公式,i=0时,Sk2(0)、E(0)、Var(0)均为0

此时UBk无意义,因此公式中,令UBk(0)=0

print(len(input_data_T))
for i in range(1, len(input_data_T)):
for j in range(i):
if input_data_T[i] > input_data_T[j]:
Sk2 = Sk2 + 1
else:
Sk2 = Sk2 + 0

Sk2_list.append(Sk2)
Exp_Sk2 = (i+1)*(i+2)/4
Exp_Sk2_value_list.append(Exp_Sk2)

Var_Sk2 = (i+1)*i*(2*(i+1)+5)/72
Var_Sk2_value_list.append(Var_Sk2)

UBk = (Sk2_list[i]-Exp_Sk2_value_list[i])/np.sqrt(Var_Sk2_value_list[i])

UBk_list.append(UBk)
UBk2_list.append(-UBk_list[i])

print(“均值矩阵”, Exp_Sk2_value_list)
print(“方差矩阵”, Var_Sk2_value_list)
print(“逆序矩阵”, UBk_list)
print(“逆序负值矩阵”, UBk2_list)
print("---------------逆向运算结束---------------")

此时上一步的到UBk表现的是逆序列在逆序时间上的趋势统计量

与UFk做图寻找突变点时,2条曲线应具有同样的时间轴,因此

再按时间序列逆转结果统计量UBk,得到时间正序的UBkT,

UBk_T_list = list(reversed(UBk2_list))

求 UFk 和 UBk_T 在同一时间下的差值

diff = np.array(UFk_list) - np.array(UBk_T_list)
K = []

找出突变点

for k in range(1, len(input_data)):
if diff[k-1] * diff[k] < 0:
K.append(k)

做突变检验图时,使用 UFk 和 UBk_T

plt.figure(figsize=(10, 5))
plt.plot(range(1, len(input_data)+1), UFk_list, label=‘UFk’) # UFk
plt.plot(range(1, len(input_data)+1), UBk_T_list, label=‘UBk’) # UBk
plt.ylabel(‘UFk-UBk’)
x_lim = plt.xlim()
plt.plot(x_lim, [-1.96, -1.96], ‘m–’, color=‘r’)
plt.plot(x_lim, [0, 0], ‘m–’)
plt.plot(x_lim, [+1.96, +1.96], ‘m–’, color=‘r’)
plt.legend(loc=2) # 图例
plt.show()
print(“突变索引号:”, K)
print(“突变年份:”, input_data[“year”][K])
input_data[‘UFK’] = UFk_list
input_data[‘UBK’] = UBk_T_list
input_data.to_csv(“输出结果.csv”) # 输出到新的csv文件,结果如下图
在这里插入图片描述

你可能感兴趣的:(python学习,python)