Mann-Kendallのトレンド検定
$$
S=\sum_{k=1}^{n-1} \sum_{j=k+1}^{n} sgn\left(X_{j}-X_{k}\right)
$$
$$
\sigma^{2}=\frac{n(n-1)(2 n+5)-\sum_{j=1}^{p} t_{j}\left(t_{j}-1\right)\left(2 t_{j}+5\right)} {18}
$$
$$
Z=\left\{\begin{array}{cl}{\frac{S-1}{\sigma}} & {\text { if } \quad S>0} \\ {0} & {\text { if } \quad S=0} \\ {\frac{S+1}{\sigma}} & {\text { if } \quad S>0}\end{array}\right.
$$
python
def Mann_Kendall(x, alpha=0.01): x = x[~np.isnan(x)].reshape(-1) n = len(x) # calculate S s = 0 for k in range(n - 1): for j in range(k + 1, n): s += np.sign(x[j] - x[k]) # calculate the unique data unique_x = np.unique(x) # calculate the var(s) tp = np.zeros(unique_x.shape) for i in range(len(unique_x)): tp[i] = np.sum(unique_x[i] == x) var_s = (n * (n - 1) * (2 * n + 5) + np.sum(tp * (tp - 1) * (2 * tp + 5))) / 18 if s > 0: z = (s - 1) / np.sqrt(var_s) elif s == 0: z = 0 elif s < 0: z = (s + 1) / np.sqrt(var_s) # calculate the p_value p = 2 * (1 - sp.stats.norm.cdf(abs(z))) # two tail test h = abs(z) > sp.stats.norm.ppf(1 - alpha / 2) if (z < 0) and h: print('decreasing') elif (z > 0) and h: print('increasing') else: print('no trend') return z, p