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

news2024/12/29 8:40:24

树是计算机科学中重要的数据结构。例如决策树等机器学习算法设计、文件系统索引等。创建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 firstnode
    elif tree.parent(nid) ==None:
        parentnode = firstnode
    else:
        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 = 0
        for 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.coloradmin.cn/o/1120654.html

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

相关文章

【Ascend C算子开发(入门)】——Ascend C编程模式与范式

Ascend C编程模型与范式 1.并行计算架构抽象 Ascend C编程开发的算子是运行在AI Core上的,所以我们需要了解一下AI Core的结构。AI Core主要包括计算单元、存储单元、搬运单元。 计算单元包括了三种计算资源:Scalar计算单元(执行标量计算&…

登上抖音同城热搜榜:如何让你的短视频成为焦点?

登上抖音同城热搜榜的首要前提是紧跟潮流,捕捉热点。热点通常具有时效性、话题性和关注度,能够迅速吸引人们的注意力。要想捕捉热点,你需要关注新闻、社交媒体和抖音热门话题,时刻关注大众关心的问题。例如,近期热门的…

rabbitMQ(3)

RabbitMq 交换机 文章目录 1. 交换机的介绍2. 交换机的类型3. 临时队列4. 绑定 (bindings)5. 扇形交换机(Fanout ) 演示6. 直接交换机 Direct exchange6.1 多重绑定6.2 direct 代码案例 7. 主题交换机7.1 Topic 匹配案例7.2 Topic 代码案例 8. headers 头…

【力扣每日一题】2023.10.22 做菜顺序

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 给我们一个数组表示每个菜的满意度,我们可以指定做哪些菜以及做的顺序,需要我们凑到一个系数的最大值&#xff0c…

第三章 内存管理 十五、内存映射文件

目录 一、传统的文件访问方式 二、内存映射文件 1、方便文件的访问 2、实现文件数据的共享 三、总结 一、传统的文件访问方式 二、内存映射文件 1、方便文件的访问 2、实现文件数据的共享 三、总结

教你注册chrome开发者账号,并发布chrome浏览器插件。

本篇文章主要讲解,注册chrome开发者账号,及发布chrome浏览器插件的流程。包含插件的打包和上传。 日期:2023年10月22日 作者:任聪聪 一、前提准备:注册chrome开发者账号 说明:注册需要5美元,一…

Qt界面容器:Widget、 Frame、分组框、滚动区、工具箱、选项卡小部件、堆叠小部件控件精讲

​Qt 界面设计容器简介 Qt中常用的容器控件, 包括: Widget, Frame, Group Box, Scroll Area, Tool Box, Tab Widget, Stacked Widget。 QWidget 这个类是所有窗口类的父类, 可以作为独立窗口使用, 也可以内嵌到其它窗口中使用。 头文件: #include <QWidget> qmake: QT…

按键控制LED灯亮灭

按键原理图&#xff1a;按键选用PE4 创建两个文件一个.c文件一个.h文件来写按键的代码 .c文件 #include "Key.h"void Key_Init(void) {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode GPIO_M…

python astra相机驱动问题

报错问题&#xff1a; openni.utils.OpenNIError: (OniStatus.ONI_STATUS_ERROR, bDeviceOpen using default: no devices found, None) 解决办法&#xff1a; 1、从sdk中拷贝文件 2、修改openni源码 3、执行测试程序 from openni import openni2 import numpy as np impor…

基于驾驶训练优化的BP神经网络(分类应用) - 附代码

基于驾驶训练优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于驾驶训练优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.驾驶训练优化BP神经网络3.1 BP神经网络参数设置3.2 驾驶训练算法应用 4.测试结果…

【C/C++笔试练习】初始化列表、构造函数、析构函数、两种排序方法、求最小公倍数

文章目录 C/C笔试练习1. 初始化列表&#xff08;1&#xff09;只能在列表初始化的变量 2.构造函数&#xff08;2&#xff09;函数体赋值&#xff08;3&#xff09;构造函数的概念&#xff08;4&#xff09;构造函数调用次数&#xff08;5&#xff09;构造函数调用次数&#xff…

自然语言处理---RNN经典案例之使用seq2seq实现英译法

1 seq2seq介绍 1.1 seq2seq模型架构 seq2seq模型架构分析&#xff1a; seq2seq模型架构&#xff0c;包括两部分分别是encoder(编码器)和decoder(解码器)&#xff0c;编码器和解码器的内部实现都使用了GRU模型&#xff0c;这里它要完成的是一个中文到英文的翻译&#xff1a;欢迎…

数据库MongoDB

MongoDB记录是一个文档&#xff0c;由一个字段和值对组成的数据结构&#xff0c;文档类似于JSON对象。 一个文档认为就是一个对象&#xff0c;字段的数据类型是字符型&#xff0c;值除了使用基本类型外&#xff0c;还可以包括其他文档&#xff0c;普通数组和文档数组。 一、…

Python —— UI自动化之使用JavaScript进行元素点亮、修改、点击元素

1、JavaScript点亮元素 在控制台通过JavaScript语言中对元素点亮效果如下&#xff1a; 将这个语句和UI自动化结合&#xff0c;代码如下&#xff1a; locator (By.ID,"kw") # 是元组类型 web_element WebDriverWait(driver,5,0.5).until(EC.visibility_of_eleme…

Windows安装virtualenv虚拟环境

需要先安装好python环境 1 创建虚拟环境目录 还是在D:\Program\ 的文件夹新建 .env 目录&#xff08;你也可以不叫这个名字&#xff0c;一般命名为 .env 或者 .virtualenv &#xff0c;你也可以在其他目录中创建&#xff09; 2 配置虚拟环境目录的环境变量 3 安装虚拟环境 进…

网络原理之UDP协议

文章目录 前言应用层协议常见的几种数据格式1. xml2. JSON3. protobuffer 端口号传输层UDP 报文协议格式源端口号和目的端口号UDP 长度校验和 前言 前面我们学习了如何使用 UDP 数据报 和 TCP 流实现网络编程一个回显服务器&#xff0c;在知道了 UDP 和 TCP 协议的基本原理之后…

Arduino驱动BMA220三轴加速度传感器(惯性测量传感器篇)

目录 1、传感器特性 2、硬件原理图 3、驱动程序 BMA220的三轴加速度计是一款具有I2C接口的超小型三轴低g加速度传感器断路器,面向低功耗消费市场应用。它可以测量3个垂直轴的加速度,从而在手机、手持设备、计算机外围设备、人机界面、虚拟现实功能和游戏控制器中感知倾斜、…

MYSQL第五章节有关约束操作详解(附代码,例题详解)这一篇就够了

c知识点合集已经完成欢迎前往主页查看&#xff0c;点点赞点点关注不迷路哦 点我进入c第一章知识点合集 MYSQL第一章节DDL数据定义语言的操作----点我进入 MYSQL第二章节DDL-数据库操作语言 DQL-数据查询语言----点我进入 MYSQL第三章节DCL-管理用户&#xff0c;控制权限----点我…

【Lua语法】字符串

Lua语言中的字符串是不可变值。不能像在C语言中那样直接改变某个字符串中的某个字符&#xff0c;但是可以通过创建一个新字符串的方式来达到修改的目的 print(add2(1 , 2 ,15,3))a "no one"b string.gsub(a , "no" , "on1111")print(a) print…

英语——名言篇——成语

爱屋及乌 Love me, love my dog.百闻不如一见 (眼见为实 ) Seeing is believing.比上不足比下有余 worse off than some, better off than many; to fall short of the best, but be better than the worst.笨鸟先飞 A slow sparrow should make an early start.不眠之夜 white…