def mk_ts(df, const, group1, orderby = 'year', alpha = 0.05):
"""
df = dataframe
const = variable tested for trend
group1 = variable to group by
orderby = variable to order by (typically a date)
"""
def zcalc(Sp, Varp):
if Sp > 0:
return (Sp - 1)/Varp**0.5
elif Sp < 0:
return (Sp + 1)/Varp**0.5
else:
return 0
df.is_copy = False
df[const] = pd.to_numeric(df.ix[:,const])
# remove null values
df[const].dropna(inplace=True)
# remove index
df.reset_index(inplace=True, drop=True)
# sort by groups, then time
df.sort_values(by=[group1,orderby],axis=0, inplace=True)
# group by group and apply mk_test
dg = df.groupby(group1).apply(lambda x: mk_test(x.loc[:,const].dropna().values, alpha))
Var_S = dg.loc[:,'varS'].sum()
S = dg.loc[:,'s'].sum()
N = dg.loc[:,'n'].sum()
Z = zcalc(S,Var_S)
P = 2*(1-norm.cdf(abs(Z)))
group_n = len(dg)
h = abs(Z) > norm.ppf(1-alpha/2)
tau = S/dg.loc[:,'ta'].sum()
if (Z<0) and h:
trend = 'decreasing'
elif (Z>0) and h:
trend = 'increasing'
else:
trend = 'no trend'
return pd.Series({'S':S, 'Z':round(Z,2), 'p':P, 'trend':trend, 'group_n':group_n, 'sample_n':N, 'Var_S':Var_S, 'tau':round(tau,2)})
评论列表
文章目录