python树结构包treelib入门及其计算应用

树是计算机科学中重要的数据结构。例如决策树等机器学习算法设计、文件系统索引等。创建treelib包是为了在Python中提供树数据结构的有效实现。

Treelib的主要特点包括:

  • 节点搜索的高效操作。
  • 支持常见的树操作,如遍历、插入、删除、节点移动、浅/深复制、子树切割等。
  • 支持用户定义的数据负载以加速您的模型构建。
  • 漂亮的树显示和文本/json 转储,用于漂亮的显示和离线分析。
  • 与 Python 2 和 3 兼容

Snyk.io是一家专注于帮助企业解决开源软件安全问题的公司,给出评价是83分。
在这里插入图片描述

1. treelib安装

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple treelib

github地址:https://github.com/caesar0301/treelib

2. 树结构应用需求

如图所示一个分层次计算因素得分,例如“流动客户”得分是由其子节点因素“货运客户”与“旅游客户”合计得到,计算公式为:货运客户的权重×货运客户的评价值+旅游客户的权重×旅游客户的评价值。
在这里插入图片描述
通用计算公式如下:
y = ∑ i = 0 n w i x i y=\sum_{i=0}^{n}{w_i x_i} y=i=0nwixi
其中, w i w_i wi为任意因素节点的权重, x i x_i xi为任意因素节点的评价得分值, y y y是这些节点的父节点。

遍历整个树,计算最后的得分,采用递归方案,程序框图如下:
在这里插入图片描述

3. 入门使用

3.1. 创建一棵树

treelib 树由Tree和Node两个类完成,其中Node是树中的节点,主要由如下内容:

  • identifier:唯一标识
  • tag:标签
  • data:数据

其他自行看源代码,包括父、子节点关系等内容。

在实际应用中,本文对“data”扩展,使用元组来定义更多的数据(0,1),0是评价得分值,1是权重。

from treelib import Node, Tree
tree = Tree()
tree.create_node("Harry", "harry",data=(None,None))  # root node
tree.create_node("Jane", "jane", parent="harry",data=(None,0.6))
tree.create_node("Bill", "bill", parent="harry",data=(None,0.4))
tree.create_node("Diane", "diane", parent="jane",data=(None,0.3))
tree.create_node("Mary", "mary", parent="jane",data=(None,0.35))
tree.create_node("Mark", "mark", parent="jane",data=(None,0.25))
tree.create_node("Green", "green", parent="bill",data=(None,0.3))
tree.create_node("White", "white", parent="bill",data=(None,0.7))

3.2. 树的简单操作

获取所有的叶子节点。

leaves = tree.leaves()
leaves
	[Node(tag=Diane, identifier=diane, data=(None, 0.3)),Node(tag=Mary, identifier=mary, data=(None, 0.35)),Node(tag=Mark, identifier=mark, data=(None, 0.25)),Node(tag=Green, identifier=green, data=(None, 0.3)),Node(tag=White, identifier=white, data=(None, 0.7))]

给叶子节点赋值,易便后续进行计算。

factors_data={'Green':20,'Mark':30,'Mary':100,'Diane':50,'White':40}
for node in leaves:node.data=(factors_data[node.tag],node.data[1])
leaves
	[Node(tag=Diane, identifier=diane, data=(50, 0.3)),Node(tag=Mary, identifier=mary, data=(100, 0.35)),Node(tag=Mark, identifier=mark, data=(30, 0.25)),Node(tag=Green, identifier=green, data=(20, 0.3)),Node(tag=White, identifier=white, data=(40, 0.7))]

获取兄弟节点。

# Return the siblings of given @nid. 获取兄弟节点
tree.siblings('diane')
	[Node(tag=Mary, identifier=mary, data=(100, 0.35)),Node(tag=Mark, identifier=mark, data=(30, 0.25))]

获取父节点。

#Get parent :class:`Node` object of given id.
tree.parent('diane')
	Node(tag=Jane, identifier=jane, data=(None, 0.6))

4. 实际应用

按权重和评价的分值,计算整颗树的各个因素的得分值。

# 计算综合评价
# 输入任意个节点(因素),endnid是约定结束节点
def calscore(tree, firstnode, endnid): nid = firstnode.identifier# 处理根节点    if (tree.parent(nid) == None or firstnode.identifier == endnid ) and firstnode.data[0]!=None:#print('root end')return firstnodeelif tree.parent(nid) ==None:parentnode = firstnodeelse:parentnode = tree.parent(nid)if firstnode.data[0]==None:# 没有计算,直接取子节点childnodes = tree.children(nid)# 计算分值calscore(tree, childnodes[0], endnid)else:# 已经计算,找兄弟节点(必须有兄弟,否则,合并节点)siblings = tree.siblings(nid)for node in siblings:           if node.data[0]==None:# 没有计算,直接取子节点childnodes = tree.children(node.identifier)# 计算分值calscore(tree, childnodes[0], endnid)# 兄弟节点都已经计算(有数据的情况),计算父节点得分siblings.append(firstnode)score = 0for node in siblings:score = score + node.data[0]*node.data[1]parentnode.data=(score,parentnode.data[1]) print(parentnode.tag ,parentnode.data)calscore(tree, parentnode, endnid)nid ='white' # 'harry'
#nid = 'jane'firstnode = tree.get_node(nid)calscore(tree, firstnode, 'harry')
# 遍历树
print(','.join([tree[node].tag + str(tree[node].data) for node in tree.expand_tree(mode=Tree.DEPTH)]))
	Harry(48.1, None),Bill(34.0, 0.4),Green(20, 0.3),White(40, 0.7),Jane(57.5, 0.6),Diane(50, 0.3),Mark(30, 0.25),Mary(100, 0.35)

5. 锦上添花画棵树

绘图使用graphviz,Graphviz 输入是一个用 dot 语言编写的绘图脚本,通过对输入脚本的解析,分析出其中的点、边及子图,然后根据属性进行绘制。

关于graphviz的使用,参见:Python安装使用graphviz经验,Format: “png“ not recognized。

# Generate DOT code file
tree.to_graphviz("hello.dot")# Can run the following command directly from the terminal as well.
import subprocess
subprocess.call(["dot", "-Tpng", "hello.dot", "-o", "graph1.png"])

关于subprocess:
运行python的时候,我们都是在创建并运行一个进程。像Linux进程那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序。在Python中,我们通过标准库中的subprocess包来fork一个子进程,并运行一个外部的程序。
subprocess包中定义有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,所以我们可以根据需要来从中选取一个使用。另外subprocess还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信。

在这里插入图片描述
此图dot描述为:

digraph tree {"harry" [label="Harry", shape=circle]"bill" [label="Bill", shape=circle]"jane" [label="Jane", shape=circle]"green" [label="Green", shape=circle]"white" [label="White", shape=circle]"diane" [label="Diane", shape=circle]"mark" [label="Mark", shape=circle]"mary" [label="Mary", shape=circle]"harry" -> "jane""harry" -> "bill""bill" -> "green""bill" -> "white""jane" -> "diane""jane" -> "mary""jane" -> "mark"
}

6. 其他树解决方案参考

使用内置的defaultdict 我们可以很容易的定义一个树形数据结构。例如参考博文【一行python实现树形结构的方法】。

def tree(): return defaultdict(tree)users = tree()
users['harold']['username'] = 'bell'
users['handler']['username'] = 'master'

我们可以使用print(json.dumps(users))以json的形式输出,于是我们看到:

	{'harold': {'username': 'bell'}, 'handler': {'username': 'master'}}

参考:

https://treelib.readthedocs.io/en/latest/
XerCis. Python树结构库treelib. CSDN博客. 2022.04
mowangdk. 一行python实现树形结构的方法 . 脚本之家. 2019.08
肖永威. Python安装使用graphviz经验,Format: “png“ not recognized. CSDN博客. 2023.10

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/118955.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Go语言测试Redis性能

1. 前言 Redis是一个高性能的键值存储数据库,常用于缓存、队列、排行榜等场景。在实际应用中,我们需要对Redis的性能进行测试,以便了解其在不同场景下的表现。本文将介绍如何使用Go语言测试Redis的性能。 2. 环境准备 在开始测试前&#x…

如何让家居设备快速通过Matter认证?移远通信为您带来标准回答

2022年10月,Matter协议正式面向全球发布;2023年10月23日,Matter 1.2最新版本正式发布。在Matter发布至今的时日里,众多头部厂商纷纷加速开发新产品,只为更快抢占市场先机,以“先发者”身份入局新赛道&#…

数据库安全定义以及重要性简单讲解

数据库安全定义 数据库安全指的是对数据库进行保护,以确保其数据的机密性、完整性和可用性,并防止非法访问、篡改、破坏、泄露等安全威胁。一般包括访问控制、数据加密、审计和监控、数据备份、漏洞修补、网络安全等方面。 数据库安全的重要性 1、数据…

C++ 学习 之 名字空间 namespace

必须在模块里面 extern 声明 在一个 cpp 文件中, 一个namespace 可以多次定义,最后合并,使用 using namespace A 这种引入方式的话,使用的时候可以用所有 A 中的数据 多个 cpp 文件的话,不能会自动合并相同的 名字空…

HackTheBox - Starting Point -- Tier 0 ---Preignition

文章目录 一 题目二 实验过程 一 题目 Tags Web、Custom Applications、Apache、Reconnaissance、Web Site Structure Discovery、Default Credentials译文:Web、定制应用程序、Apache、侦察、网站结构发现、默认凭证Connect To attack the target machine, you …

论文-分布式-分布式计算|容错-分布式控制下的自稳定系统

参考文献Self-stabilizing systems in spite of distributed control可以把松散耦合的 循环序列过程 间的同步任务,看成是要保持一个这样的不变性:“系统要处于一种合法状态”因此每个进程在运行每一个可能会改变不变性的步骤之前都要先检查一下是可以执…

人机环境系统智能是东方与西方智能思想的融合

人机环境系统的思想是一种综合性的思想,它融合了东方思想和西方思想的元素。在东方文化中,人类与自然环境有着密切的联系,强调人类与自然环境的和谐共生关系。而在西方文化中,科技和机器的应用越来越广泛,对人类社会和…

21.2 Python 使用Scapy实现端口探测

Scapy 是一款使用纯Python编写的跨平台网络数据包操控工具,它能够处理和嗅探各种网络数据包。能够很容易的创建,发送,捕获,分析和操作网络数据包,包括TCP,UDP,ICMP等协议,此外它还提…

十四天学会C++之第八天:文件操作

1. 文件的打开和关闭 文件操作的基本概念。打开文件:使用fstream库打开文件以供读写。关闭文件:确保文件在使用完毕后正确关闭。 文件的打开和关闭:C 文件操作入门 在C编程中,文件操作是一项重要的任务,可以读取和写…

《Cesium 进阶知识点》- el-select 列表打开后,点击Cesium.Viewer场景无法自动关闭

前提 el-select属性 popper-append-to-body 必须 为 false。这样初始化的列表 el-select-dropdown 才在 el-select下;目前测试,仅对 Cesium.Viewer 生成的 canvas 点击时列表无法自动关闭;使用原生 canvas 和 echarts,点击其场景…

vivado简单仿真入门

打开软件 创建工程 create project ![在这里插入图片描述](https://img-blog.csdnimg.cn/892eda626d394733920854b71ca8f726.png)先next,保留工程路径,配置环境 配置芯片环境 本次芯片类型 xc7k325tffg900-2 创建之后完整的demo 编写仿真内容 timescale 1ns/1…

RabbitMQ 笔记

一、win10安装erlang 1.1 安装erLang语言,配置环境变量 erLang官网地址 1.2 配置环境变量 (1)添加系统变量ERLANG_HOME (2)path路径,指向bin目录 1.3 配置完成后再cmd命令窗口erl -version可以查看…

管理类联考——数学——汇总篇——知识点突破——数据分析——记忆

文章目录 考点记忆/考点汇总——按大纲 整体目录大纲法记忆宫殿法绘图记忆法 局部数字编码法对号不对号 归类记忆法重点记忆法歌决记忆法口诀:加法分类,类类相加;乘法分步,步步相乘。 谐音记忆法涂色 理解记忆法比较记忆法转图像记…

1997-2017年各省能源投入数据(万吨标准煤)

1997-2017年各省能源投入数据(万吨标准煤) 1、时间:1997-2017年 2、来源:中国统计年鉴 3、范围:30个省 4、指标:能源投入(各省8种能源消费总量计算得出)(万吨标准煤&…

DeepSpeed: 大模型训练框架 | 京东云技术团队

背景: 目前,大模型的发展已经非常火热,关于大模型的训练、微调也是各个公司重点关注方向。但是大模型训练的痛点是模型参数过大,动辄上百亿,如果单靠单个GPU来完成训练基本不可能。所以需要多卡或者分布式训练来完成这…

华为NAT配置实例(含dhcp、ospf配置)

一、网络拓朴如下: 二、要求:PC1 能访问到Server1 三、思路: R2配置DHCP,R2和R1配OSPF,R1出NAT 四、主要配置: R2的DHCP和OSPF: ip pool 1gateway-list 10.1.1.1 network 10.1.1.0 mask 25…

Leetcode—7.整数反转【中等】

2023每日刷题&#xff08;十&#xff09; Leetcode—7.整数反转 关于为什么要设long变量 参考自这篇博客 long可以表示-2147483648而且只占4个字节&#xff0c;所以能满足题目要求 复杂逻辑版实现代码 int reverse(int x){int arr[32] {0};long y;int flag 1;if(x <…

JS操作DOM及CSS

JS创造于1994年&#xff0c;其目的是为浏览器显示的文档赋予动态行为。 1 Web编程基础 本节讲解如何编写Web应用中的js程序&#xff0c;如果将这些程序加载到浏览器&#xff0c;以及如何获取输入、产出输出&#xff0c;如何运行响应事件的异步代码。 1.1 js 脚本 虽然现在不…

什么是 Node.js

目标 什么是 Node.js&#xff0c;有什么用&#xff0c;为何能独立执行 JS 代码&#xff0c;演示安装和执行 JS 文件内代码 讲解 Node.js 是一个独立的 JavaScript 运行环境&#xff0c;能独立执行 JS 代码&#xff0c;因为这个特点&#xff0c;它可以用来编写服务器后端的应用…

mybatisPlus逻辑删除注解@TableLogic

当我做了一个实体类&#xff0c;字段为del_flag的逻辑删除字段&#xff0c;要通过这个字段控制数据库中的数据逻辑删除。 重写mapper中的deleteById&#xff0c; 先按id查出数据&#xff0c;在更新此数据中的del_flag字段为1&#xff0c;调用update方法更新数据。 这种方式我…