def score1(sta_ob_and_fos0,method,s = None,g = None,gll = None,para1 = None,para2 = None,plot = "line",show = False,excel_path = None): if s is not None: if g is not None: if g == "last_range" or g == "last_step": s["drop_last"] = False else: s["drop_last"] = True sta_ob_and_fos = sele_by_dict(sta_ob_and_fos0, s) if type(method) == str: method = globals().get(method) if method == meteva.method.FSS_time: if g == "dtime": print("FSS_time 检验时,参数group_by不能选择dtime") return sta_ob_and_fos_list,group_list_list1 = group(sta_ob_and_fos,g,gll) data_name = meteva.base.get_stadata_names(sta_ob_and_fos) fo_num = len(data_name) -1 ensemble_score_method = [meteva.method.cr] group_num = len(sta_ob_and_fos_list) if para1 is None: para_num = 1 else: para_name_list = [] mutil_list = [meteva.method.ts_multi,meteva.method.bias_multi,meteva.method.ets_multi, meteva.method.mr_multi,meteva.method.far_multi] if method in mutil_list: para_num = len(para1)+1 para_name_list = ["<" + str(para1[0])] for i in range(len(para1)-1): para_name_list.append("["+str(para1[i]) + ","+str(para1[i+1])+")") para_name_list.append(">=" + str(para1[-1])) else: para_num = len(para1) for i in range(len(para1)): para_name_list.append(para1[i]) sta_result = None if method == meteva.method.FSS_time: #统计dtime的集合 dtime_list = list(set(sta_ob_and_fos["dtime"].values.tolist())) dtime_list.sort() ndtime = len(dtime_list) result= [] for sta_ob_and_fo in sta_ob_and_fos_list: # 将观测和预报数据重新整理成FSS_time所需格式 ob = in_member_list(sta_ob_and_fo,[data_name[0]]) ob_dtimes = None for k in range(ndtime): dtimek = dtime_list[k] sta_obk = in_dtime_list(ob,[dtimek]) set_stadata_names(sta_obk,[data_name[0]+ str(dtimek)]) ob_dtimes = combine_on_leve_time_id(ob_dtimes,sta_obk) result1 = [] #print(ob_dtimes) ob_array = ob_dtimes.values[:,6:] for j in range(fo_num): fo = in_member_list(sta_ob_and_fo, [data_name[j+1]]) fo_dtimes = None for k in range(ndtime): dtimek = dtime_list[k] sta_fok = in_dtime_list(fo, [dtimek]) set_stadata_names(sta_fok, [data_name[j+1] + str(dtimek)]) fo_dtimes = combine_on_leve_time_id(fo_dtimes, sta_fok) fo_array = fo_dtimes.values[:,6:] #调用检验程序 if para1 is None: para1 = [1e-30] result2 = FSS_time(ob_array, fo_array, para1, para2) result1.append(result2) result.append(result1) result = np.array(result) #将数据转换成数组 result = result.squeeze() else: nead_lon_lat = False if g == "id" and gll is None: nead_lon_lat = True lon_lat_list = [] if method in ensemble_score_method: result = np.zeros((group_num,para_num)) for i in range(group_num): sta = sta_ob_and_fos_list[i] #if(len(sta.index) == 0): # result[i,:] = meteva.base.IV #else: ob = sta[data_name[0]].values fo = sta[data_name[1:]].values if para1 is None: result[i, :] = method(ob, fo) else: result[i,:] = method(ob, fo,para1) if nead_lon_lat: lon_lat_list.append(sta.iloc[0,[4,5]]) else: if fo_num ==0: result = np.zeros((group_num,para_num)) else: result = np.zeros((group_num,fo_num,para_num)) for i in range(group_num): #print(group_num) sta = sta_ob_and_fos_list[i] #if(len(sta.index) == 0): # result[i,:] = meteva.base.IV #else: ob = sta[data_name[0]].values if fo_num>0: for j in range(fo_num): fo = sta[data_name[j+1]].values if para1 is None: result[i, j] = method(ob, fo) else: result[i,j] = method(ob, fo,para1) else: if para1 is None: result[i] = method(ob, None) else: result[i] = method(ob, None,para1) if nead_lon_lat: lon_lat_list.append(sta.iloc[0,[4,5]]) # 将结果输出到excel if excel_path is not None: meteva.base.creat_path(excel_path) if fo_num ==0: fo_num = 1 result.reshape([group_num,fo_num,para_num]) group_dict ={"group":group_list_list1} model_dict = {"member":data_name[1:]} para_dict = {"threshold":para_name_list} name_dict_list = [group_dict,model_dict,para_dict] meteva.base.write_array_to_excel(result,excel_path,name_dict_list) result = result.squeeze() if nead_lon_lat: df = pd.DataFrame(lon_lat_list) df["id"] = group_list_list1 df["level"] = np.NAN df["time"] = np.NAN df["dtime"] = np.NAN if fo_num ==0: if para1 is None: df["ob"] = result else: if isinstance(para1,list): for i in range(len(para1)): para = para1[i] df[para] = result[:,i] else: df[para1] = result else: result = result.reshape(group_num,fo_num,para_num) for j in range(fo_num): if para1 is None: df[data_name[1+j]] = result[:,j,0] else: if isinstance(para1, list): for i in range(len(para1)): para = para1[i] df[data_name[1+j]+"_"+str(para)] = result[:,j, i] else: df[data_name[1 + j]] = result[:,j,0] sta_result = sta_data(df) if show: if plot == "line": if g == "dtime": x = np.arange(len(group_list_list1)) plt.plot(result,label = data_name[1]) plt.xticks(x,group_list_list1) plt.xlabel("预报时效") plt.ylabel("ME") plt.legend() plt.show() return result,group_list_list1,sta_result
def score(sta_ob_and_fos0, method, s=None, g=None, gll=None, group_name_list=None, plot=None, save_path=None, show=False, dpi=300, title="", excel_path=None, **kwargs): if s is not None: if g is not None: if g == "last_range" or g == "last_step": s["drop_last"] = False else: s["drop_last"] = True sta_ob_and_fos = sele_by_dict(sta_ob_and_fos0, s) if type(method) == str: method = globals().get(method) if method == meteva.method.FSS_time: if g == "dtime": print("FSS_time 检验时,参数group_by不能选择dtime") return sta_ob_and_fos_list, group_list_list1 = group(sta_ob_and_fos, g, gll) group_num = len(sta_ob_and_fos_list) data_name = meteva.base.get_stadata_names(sta_ob_and_fos_list[0]) if method.__name__.find("ob_fo") >= 0: fo_name = data_name else: ensemble_score_method = [meteva.method.cr] if method in ensemble_score_method: fo_name = [""] else: fo_name = data_name[1:] fo_num = len(fo_name) #等级参数的确定 if "grade_list" not in kwargs.keys(): mutil_list = [ meteva.method.ts_multi, meteva.method.bias_multi, meteva.method.ets_multi, meteva.method.mr_multi, meteva.method.far_multi ] if method in mutil_list: # 如果是多分类检验,但又没有设置分级方法,就需要从数据中获得全局的种类 values = sta_ob_and_fos.iloc[:, 6:].flatten() index_list = list(set(values)) if len(index_list) > 30: print("自动识别的样本类别超过30种,判断样本为连续型变量,grade_list不能缺省") return index_list.sort() grade_list = [] for i in range(len(index_list) - 1): grade_list.append((index_list[i] + index_list[i + 1]) / 2) kwargs["grade_list"] = grade_list if "grade_list" in kwargs.keys(): grades = kwargs["grade_list"] grade_names = [] mutil_list1 = [ meteva.method.ts_multi, meteva.method.bias_multi, meteva.method.ets_multi, meteva.method.mr_multi, meteva.method.far_multi ] mutil_list2 = [ meteva.method.accuracy, meteva.method.hk, meteva.method.hss ] if method in mutil_list1: grade_names = ["<" + str(grades[0])] for i in range(len(grades) - 1): grade_names.append("[" + str(grades[i]) + "," + str(grades[i + 1]) + ")") grade_names.append(">=" + str(grades[-1])) elif method in mutil_list2: grade_names = ["0"] else: for i in range(len(grades)): grade_names.append(grades[i]) else: grade_names = ["0"] grade_num = len(grade_names) if method == meteva.method.FSS_time: #统计dtime的集合 dtime_list = list(set(sta_ob_and_fos["dtime"].values.tolist())) dtime_list.sort() ndtime = len(dtime_list) result = [] for sta_ob_and_fo in sta_ob_and_fos_list: # 将观测和预报数据重新整理成FSS_time所需格式 ob = in_member_list(sta_ob_and_fo, [data_name[0]]) ob_dtimes = None for k in range(ndtime): dtimek = dtime_list[k] sta_obk = in_dtime_list(ob, [dtimek]) set_stadata_names(sta_obk, [data_name[0] + str(dtimek)]) ob_dtimes = combine_on_leve_time_id(ob_dtimes, sta_obk) result1 = [] #print(ob_dtimes) ob_array = ob_dtimes.values[:, 6:] for j in range(fo_num): fo = in_member_list(sta_ob_and_fo, [data_name[j + 1]]) fo_dtimes = None for k in range(ndtime): dtimek = dtime_list[k] sta_fok = in_dtime_list(fo, [dtimek]) set_stadata_names(sta_fok, [data_name[j + 1] + str(dtimek)]) fo_dtimes = combine_on_leve_time_id(fo_dtimes, sta_fok) fo_array = fo_dtimes.values[:, 6:] #调用检验程序 result2 = FSS_time(ob_array, fo_array, **kwargs) result1.append(result2) result.append(result1) result = np.array(result) #将数据转换成数组 result = result.squeeze() else: result_list = [] for i in range(group_num): sta = sta_ob_and_fos_list[i] #if(len(sta.index) == 0): # result[i,:] = meteva.base.IV #else: ob = sta[data_name[0]].values fo = sta[data_name[1:]].values.T result1 = method(ob, fo, **kwargs) result_list.append(result1) result = np.array(result_list) if plot is not None or excel_path is not None: result_plot = result.reshape((group_num, fo_num, grade_num)) name_list_dict = {} if g is None: group_dict_name = "group_name" else: group_dict_name = g #设置分组名称 if group_name_list is not None: if group_num == len(group_name_list): name_list_dict[group_dict_name] = group_name_list else: print("group_name_list参数中包含的分组名称个数和实际分组个数不匹配") else: if not isinstance(group_list_list1, list): group_list_list1 = [group_list_list1] name_list_dict[group_dict_name] = get_group_name(group_list_list1) #设置成员名称 name_list_dict["member"] = fo_name #设置等级名称 name_list_dict["grade"] = grade_names keys = list(name_list_dict.keys()) if fo_num == 1: if grade_num > 1: legend = keys[0] axis = keys[2] else: axis = keys[0] legend = keys[1] else: if group_num == 1: if grade_num > 1: legend = keys[1] axis = keys[2] else: legend = keys[2] axis = keys[1] else: legend = keys[1] axis = keys[0] ylabel = method.__name__.upper() bigthan0_method = [ meteva.method.ts, meteva.method.ob_fo_hr, meteva.method.ob_fo_std, meteva.method.ts_multi, meteva.method.s, meteva.method.pc_of_sun_rain, meteva.method.bias_multi, meteva.method.bias, meteva.method.pc, meteva.method.mr, meteva.method.far, meteva.method.tc, meteva.method.roc_auc, meteva.method.r, meteva.method.sr, meteva.method.cr, meteva.method.pod, meteva.method.pofd, meteva.method.mse, meteva.method.rmse, meteva.method.mae ] if method in bigthan0_method: vmin = 0 else: vmin = None if plot is not None: if plot == "bar": meteva.base.plot_tools.bar(result_plot, name_list_dict, legend=legend, axis=axis, vmin=vmin, ylabel=ylabel, save_path=save_path, show=show, dpi=dpi, title=title) else: meteva.base.plot_tools.plot(result_plot, name_list_dict, legend=legend, axis=axis, vmin=vmin, ylabel=ylabel, save_path=save_path, show=show, dpi=dpi, title=title) if excel_path is not None: meteva.base.write_array_to_excel(result_plot, excel_path, name_list_dict, index=axis, columns=legend) result = result.squeeze() return result, group_list_list1
def score(sta_ob_and_fos, method, group_by=None, group_list_list=None, para1=None, para2=None): if type(method) == str: method = globals().get(method) if method == meteva.method.FSS_time: if group_by == "dtime": print("FSS_time 检验时,参数group_by不能选择dtime") return sta_ob_and_fos_list, group_list_list1 = group(sta_ob_and_fos, group_by, group_list_list) data_name = meteva.base.get_stadata_names(sta_ob_and_fos) fo_num = len(data_name) - 1 ensemble_score_method = [meteva.method.cr] group_num = len(sta_ob_and_fos_list) if para1 is None: para_num = 1 else: para_num = len(para1) if method in ensemble_score_method: result = np.zeros((group_num, para_num)) for i in range(group_num): sta = sta_ob_and_fos_list[i] if (len(sta.index) == 0): result[i, :] = meteva.base.IV else: ob = sta[data_name[0]].values fo = sta[data_name[1:]].values if para1 is None: result[i, :] = method(ob, fo) else: result[i, :] = method(ob, fo, para1) elif method == meteva.method.FSS_time: #统计dtime的集合 dtime_list = list(set(sta_ob_and_fos["dtime"].values.tolist())) dtime_list.sort() ndtime = len(dtime_list) result = [] for sta_ob_and_fo in sta_ob_and_fos_list: # 将观测和预报数据重新整理成FSS_time所需格式 ob = in_member_list(sta_ob_and_fo, [data_name[0]]) ob_dtimes = None for k in range(ndtime): dtimek = dtime_list[k] sta_obk = in_dtime_list(ob, [dtimek]) set_stadata_names(sta_obk, [data_name[0] + str(dtimek)]) ob_dtimes = combine_on_leve_time_id(ob_dtimes, sta_obk) result1 = [] #print(ob_dtimes) ob_array = ob_dtimes.values[:, 6:] for j in range(fo_num): fo = in_member_list(sta_ob_and_fo, [data_name[j + 1]]) fo_dtimes = None for k in range(ndtime): dtimek = dtime_list[k] sta_fok = in_dtime_list(fo, [dtimek]) set_stadata_names(sta_fok, [data_name[j + 1] + str(dtimek)]) fo_dtimes = combine_on_leve_time_id(fo_dtimes, sta_fok) fo_array = fo_dtimes.values[:, 6:] #调用检验程序 if para1 is None: para1 = [1e-30] result2 = FSS_time(ob_array, fo_array, para1, para2) result1.append(result2) result.append(result1) result = np.array(result) #将数据转换成数组 else: if fo_num == 0: result = np.zeros((group_num, para_num)) else: result = np.zeros((group_num, fo_num, para_num)) for i in range(group_num): #print(group_num) sta = sta_ob_and_fos_list[i] if (len(sta.index) == 0): result[i, :] = meteva.base.IV else: ob = sta[data_name[0]].values if fo_num > 0: for j in range(fo_num): fo = sta[data_name[j + 1]].values if para1 is None: result[i, j] = method(ob, fo) else: result[i, j] = method(ob, fo, para1) else: if para1 is None: result[i] = method(ob, None) else: result[i] = method(ob, None, para1) result = result.squeeze() return result, group_list_list1