def lowess_homemade_kern(x, y, w, a1, kernel='Exp'): """ #inspired by: https://xavierbourretsicotte.github.io/loess.html homebaked lowess with variogram kernel + heteroscedasticity of observations with error :param x:x :param y:y :param w: heteroscedastic weights (inverse of variance) :param a1: range of the kernel (in variogram terms) :param kernel: kernel function :return: """ n = len(x) yest = np.zeros(n) err_yest = np.zeros(n) if kernel == 'Gau': kernel_fun = kernel_gaussian elif kernel == 'Exp': kernel_fun = kernel_exp elif kernel == 'Exc': kernel_fun = kernel_exclass else: print('Kernel not recognized.') sys.exit() W = np.array([kernel_fun(x, x[i], a1) * w for i in range(n)]).T X = np.array([x for i in range(n)]).T Y = np.array([y for i in range(n)]).T beta1, beta0, _, Yl, Yu = ft.wls_matrix(X, Y, W, conf_interv=0.68) for i in range(n): yest[i] = beta1[i] * x[i] + beta0[i] err_yest[i] = (Yu[i, i] - Yl[i, i]) / 2 return yest, err_yest
# new_err_vals[i] = np.nanmean(err_vals[ind]) # data_vals = new_data_vals # time_vals = new_time_vals # err_vals = new_err_vals # good_vals = np.isfinite(data_vals) # here we need to change the 0 for the x axis, in case we are using a linear kernel ax = fig.add_subplot(grid[6:12,5:]) ax.text(0.025, 0.95, 'd', transform=ax.transAxes, fontsize=16, fontweight='bold', va='top', ha='left') while (n_out > 0 or final_fit==0) and num_finite >= 2: beta1, beta0, incert_slope, _, _ = ft.wls_matrix(time_vals[good_vals], data_vals[good_vals], 1. / err_vals[good_vals], conf_slope=0.99) # standardized dispersion from linearity res_stdized = np.sqrt(np.mean( (data_vals[good_vals] - (beta0 + beta1 * time_vals[good_vals])) ** 2 / err_vals[good_vals])) res = np.sqrt(np.mean((data_vals[good_vals] - (beta0 + beta1 * time_vals[good_vals])) ** 2)) if perc_nonlin[min(niter, len(perc_nonlin) - 1)] == 0: opt_var = 0 else: opt_var = (res / res_stdized ** 2) ** 2 * 100. / (5 * perc_nonlin[min(niter, len(perc_nonlin) - 1)]) k1 = PairwiseKernel(1, metric='linear') + PairwiseKernel(1, metric='linear') * C(opt_var) * RQ(10, 3) # linear kernel k2 = C(30) * ESS(length_scale=1, periodicity=1) # periodic kernel k3 = C(50) * RBF(0.75) kernel = k1 + k2 + k3
def bin_valid_df_by_vals(df, bins, bins_val, list_var=['dh', 'zsc'], ls_dvardt=True, weight_ib=1. / 40, return_ls=False): mid_bin, med, std, dvardt, dvardt_2std, ns_ics, ns_ib = ([] for i in range(7)) for i in range(len(bins) - 1): ind = np.logical_and(bins_val >= bins[i], bins_val < bins[i + 1]) df_ind = df[ind] nics = np.count_nonzero(df_ind.sensor == 'ICS') nib = np.count_nonzero(df_ind.sensor == 'IB') ns_ics.append(nics) ns_ib.append(nib) mid_bin.append(bins[i] + 0.5 * (bins[i + 1] - bins[i])) sub_med = [] sub_std = [] sub_dvardt = [] sub_dvardt_2std = [] sub_mu = [] sub_w = [] sub_t = [] for var in list_var: if weight_ib is not None: if nics != 0 or nib != 0: sub_med.append( np.nansum( (np.nanmedian( df_ind[df_ind.sensor == 'ICS'][var]) * nics, np.nanmedian(df_ind[df_ind.sensor == 'IB'][var]) * nib * weight_ib)) / (nics + nib * weight_ib)) sub_std.append( np.nansum( (nmad(df_ind[df_ind.sensor == 'ICS'][var]) * nics, nmad(df_ind[df_ind.sensor == 'IB'][var]) * nib * weight_ib)) / (nics + nib * weight_ib)) else: sub_med.append(np.nan) sub_std.append(np.nan) else: sub_med.append(np.nanmedian(df_ind[var])) sub_std.append(nmad(df_ind[var].values)) if ls_dvardt: list_t = sorted(list(set(list(df_ind.t.values)))) ftime_delta = np.array([ (np.datetime64(t) - np.datetime64('{}-01-01'.format(int(2000)))).astype(int) / 365.2422 for t in list_t ]) mu = [] w = [] for val_t in list_t: ind_t = df_ind.t.values == val_t df_ind_t = df_ind[ind_t] nics_t = np.count_nonzero(df_ind_t.sensor == 'ICS') nib_t = np.count_nonzero(df_ind_t.sensor == 'IB') if np.count_nonzero(ind_t) > 20: med_t = np.nansum( (np.nanmedian( df_ind_t[df_ind_t.sensor == 'ICS'][var]) * nics_t, np.nanmedian( df_ind_t[df_ind_t.sensor == 'IB'][var]) * nib_t * weight_ib)) / (nics_t + nib_t * weight_ib) mu.append(med_t) std_t = np.nansum( (nmad(df_ind_t[df_ind_t.sensor == 'ICS'][var]) * nics_t, nmad(df_ind_t[df_ind_t.sensor == 'IB'][var]) * nib_t * weight_ib)) / (nics_t + nib_t * weight_ib) w.append(std_t / np.sqrt(nics_t + nib_t * weight_ib)) else: mu.append(np.nan) w.append(np.nan) mu = np.array(mu) w = np.array(w) if np.count_nonzero(~np.isnan(mu)) > 5: # reg = LinearRegression().fit(ftime_delta[~np.isnan(mu)].reshape(-1, 1), # mu[~np.isnan(mu)].reshape(-1, 1)) beta1, _, incert_slope, _, _ = ft.wls_matrix( ftime_delta[~np.isnan(mu)], mu[~np.isnan(mu)], 1. / w[~np.isnan(mu)]**2, conf_slope=0.95) # fig = plt.figure() # plt.scatter(ftime_delta,mu_dh,color='red') # plt.plot(np.arange(0,10,0.1),reg.predict(np.arange(0,10,0.1).reshape(-1,1)),color='black',label=reg) # plt.ylim([-20,20]) # plt.text(5,0,str(reg.coef_[0])) # plt.legend() # coef = reg.coef_[0][0] coef = beta1 sub_dvardt.append(coef) sub_dvardt_2std.append(incert_slope) else: sub_dvardt.append(np.nan) sub_dvardt_2std.append(np.nan) sub_mu.append(mu) sub_w.append(w) sub_t.append(ftime_delta) med.append(sub_med) std.append(sub_std) dvardt.append(sub_dvardt) dvardt_2std.append(sub_dvardt_2std) df_out = pd.DataFrame() df_out = df_out.assign(mid_bin=mid_bin, ns_ics=ns_ics, ns_ib=ns_ib) for var in list_var: df_out['med_' + var] = list(zip(*med))[list_var.index(var)] df_out['nmad_' + var] = list(zip(*std))[list_var.index(var)] if ls_dvardt: df_out['d' + var + '_dt'] = list(zip(*dvardt))[list_var.index(var)] df_out['d' + var + '_dt_2std'] = list( zip(*dvardt_2std))[list_var.index(var)] if return_ls and ls_dvardt: df_ls = pd.DataFrame() for var in list_var: # print(len(sub_mu)) df_ls['mu_' + var] = sub_mu[list_var.index(var)] df_ls['w_' + var] = sub_w[list_var.index(var)] df_ls['t_' + var] = sub_t[list_var.index(var)] return df_out, df_ls else: return df_out
'2000-01-01_2020-01-01'].err_dmdt.values[0]) + ' Gt yr-1') print('Glacier mass loss totalled ' + '{:.3f}'.format(glac_trend) + ' ± ' + '{:.3f}'.format(2 * glac_trend_err) + ' mm of sea-level rise') contr_trend = -glac_trend / gmsl_trend * 100 contr_trend_err = -glac_trend / gmsl_trend * np.sqrt( (gmsl_trend_err / gmsl_trend)**2 + (glac_trend_err / glac_trend)**2) * 100 print('Glacier contribution to SLR is ' + '{:.2f}'.format(contr_trend) + ' % ± ' + '{:.2f}'.format(2 * contr_trend_err) + ' %') #GLACIER ACCELERATION beta1_t, beta0, incert_slope, _, _ = ft.wls_matrix( x=np.arange(0, 16, 5), y=df_g.dhdt.values[:-1], w=1 / df_g.err_dhdt.values[:-1]**2) print('Global thinning acceleration is ' + '{:.5f}'.format(beta1_t) + ' ± ' + '{:.5f}'.format(2 * incert_slope) + ' m yr-2') beta1, beta0, incert_slope, _, _ = ft.wls_matrix(x=np.array([0, 5, 10, 15]), y=df_np.dhdt.values[:-1], w=1 / df_np.err_dhdt.values[:-1]**2) print('Global excl. GRL and ANT thinning acceleration is ' + '{:.5f}'.format(beta1) + ' ± ' + '{:.5f}'.format(2 * incert_slope) + ' m yr-2') beta1_g, beta0, incert_slope_g, _, _ = ft.wls_matrix( x=np.arange(0, 16, 5), y=df_g.dmdt.values[:-1], w=1 / df_g.err_dmdt.values[:-1]**2)