树形结构数据向上聚合(python)

思路:

  1、把所有节点递归添加到一个集合里,每个对象是一个字典数据,规定每个对象的id和父id(注意递归添加的顺序)

  2、处理集合,使用倒序把子节点的数据聚合给父节点(for倒序循环,判断当前节点(父节点)的数据不存在,内层遍历集合所有节点,把父id是当前节点id的节点拿出放到新集合处理)

  3、循环完成后,最上层节点数据就聚合Ok,遍历集合,根据id拿自己要的节点数据就好了

  因为我遍历的集合存在时间不统一,索引长度也就不一样。另加判断处理。

代码:

  递归添加节点数据到集合(首先拿到第二层节点)

 

data = []   # 表格、雷达图和线状图所需数据  格式:[{"aaa":"1","bbb":"2".......}]
x_values = [] # 线状图x坐标集,第二层节点的日期集合
y_values = [] # 线状图y坐标集,第二层节点的数据集合
sql
sql
sql
sql
children_nodes = db.query_sql(query_childrens_sql % target_id)
all_node_data = []
getAll_node_data_to_list(children_nodes,all_node_data,sql_queryAtom_all_details,query_childrens_sql,query_parent_sql,start_time,end_time) #递归方法
#这样就得到二级节点及以下所有节点的对象集合,递归方法看最下面
for i in range(len(all_node_data)):
# 从集合最后一项向前处理数据
if len(all_node_data[len(all_node_data)-i-1]["atom_data"]) == 0:
id = all_node_data[len(all_node_data)-i-1]["id"]
algorithm_name = all_node_data[len(all_node_data)-i-1]["algorithm_name"] # 拿到父节点的聚合算法
handle_data = []
for node_data in all_node_data:
if node_data["parent_node_id"] == id:
handle_data.append(node_data)
if len(handle_data) == 1:
handle_data1 = handle_data[0]
all_node_data[len(all_node_data)-i-1]["atom_data"] = handle_data1["atom_data"]
if len(handle_data) == 2:
length_list = []
handle_data1 = handle_data[0]
length_list.append(len(handle_data1["atom_data"]))
handle_data2 = handle_data[1]
length_list.append(len(handle_data2["atom_data"]))
for j in range(min(length_list)):
dict_data = {}
dict_data['clock'] = handle_data1["atom_data"][j]['clock']
if int(algorithm_name) == 2: # 平均值计算
dict_data['value'] = (float(handle_data1["atom_data"][j]['value']) + float(handle_data2["atom_data"][j]['value']))/2
if int(algorithm_name) == 3:  # 最大值计算
details_data_list = []
details_data_list.append(float(handle_data1["atom_data"][j]['value']))
details_data_list.append(float(handle_data2["atom_data"][j]['value']))
dict_data['value'] = max(details_data_list)
if int(algorithm_name) == 4:
details_data_list = []
details_data_list.append(float(handle_data1["atom_data"][j]['value']))
details_data_list.append(float(handle_data2["atom_data"][j]['value']))
dict_data['value'] = min(details_data_list)
dict_data['value'] = float(handle_data1["atom_data"][j]['value']) + float(handle_data2["atom_data"][j]['value'])
if int(algorithm_name) == 11:
dict_data['value'] = float(handle_data1["atom_data"][j]['value']) * float(handle_data2["atom_data"][j]['value'])
all_node_data[len(all_node_data)-i-1]["atom_data"].append(dict_data)
列举了1~2个子节点的运算,多节点请照猫画虎

得到处理完成的list集合,接下来拿数据就行了
for node_data in all_node_data:
if node_data['parent_node_id'] == target_id:
atom_data = node_data['atom_data']
each_x_values = []
each_y_values = []
for each_data in atom_data:
timeArray = time.localtime(each_data['clock'] + 8*60*60)
otherStyleTime = time.strftime("%Y--%m--%d %H:%M:%S", timeArray)
each_x_values.append(otherStyleTime)
each_y_values.append(float(each_data['value']))
avg_data = sum(each_y_values) / len(each_y_values)
attack_score += round(avg_data,3)
attack_score_list.append(round(avg_data,3))
dict_data_values[node_data['assess_name']] = round(avg_data,3)
x_values.append(each_x_values)
# 线型图y轴数值归一化
normalization_y_values = []
for i in range(len(each_y_values)):
if max(each_y_values) == 0:
normalization_y_values.append(0)
else:
normalization_y_values.append((each_y_values[i]-min(each_y_values))/(max(each_y_values)-min(each_y_values)))
y_values.append(normalization_y_values)
data.append(dict_data_values)

以下是递归添加数据的方法:
def getAll_node_data_to_list(children_nodes,all_node_data,sql_queryAtom_all_details,query_childrens_sql,query_parent_sql,start_time,end_time):
if len(children_nodes) > 0:
for children_node in children_nodes:
each_node_data = {}
each_node_data["id"] = children_node["id"]
each_node_data["algorithm_name"] = children_node["algorithm_name"]
each_node_data["assess_name"] = children_node["assess_name"]
       # 判断是否最后一层节点,我的规则是绑定原子数据的就为最后一层,直接把数据添加到对象的atom_data中,这样就能保证最底层节点存在数据,聚合的时候父节点可以拿这些数据进行处理
if children_node["atom_id"] == "" or children_node["atom_id"] is None:
each_node_data["atom_data"] = []
else:
params = (children_node["atom_id"] or "", start_time or "", end_time or "")
atom_data = db.query_sql(sql_queryAtom_all_details % params)
each_node_data["atom_data"] = atom_data
each_node_data["parent_node_id"] = db.query_sql(query_parent_sql % children_node["id"])[0]["pid"]
all_node_data.append(each_node_data)
children_nodes = db.query_sql(query_childrens_sql % children_node["target_id"])
getAll_node_data_to_list(children_nodes,all_node_data,sql_queryAtom_all_details,query_childrens_sql,query_parent_sql,start_time,end_time,)
sql语句就不放这了,自己写吧。啊哈哈哈哈哈哈哈哈哈哈哈哈
上一篇:踏上全球数字化征程 | LTD&营销SaaS参加首届亚太域名系统论坛 (APAC DNS Forum)


下一篇:C语言单链表学习