You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中基于Pandas DataFrame绘制树状图的技术疑问及求解

解决从Pandas DataFrame绘制网络通信树状图的问题

首先,咱们得先把你的数据转换成树结构需要的层级格式,再选合适的工具来可视化。你的数据包含source(源IP)、destination(目标IP)、application(应用)和timemark(时间戳),要构建的树层级应该是:Source → Destination → Application(如果需要,还可以把timemark作为节点的附加信息)。

步骤1:数据预处理(清洗与分组)

首先得对DataFrame做分组和去重,避免重复节点。比如同一对source-destination下可能有多个相同的application记录(不同时间戳),可以先按source、destination、application分组,保留唯一组合,或者把timemark聚合起来(比如收集所有时间戳、统计通信次数)。

假设你的DataFrame叫df,先做预处理:

import pandas as pd

# 示例数据(模拟你的数据集)
data = {
    'source': ['192.168.1.1', '192.168.1.1', '192.168.1.2', '192.168.1.1'],
    'destination': ['192.168.1.200', '192.168.1.200', '192.168.1.100', '192.168.1.300'],
    'application': ['ping', 'http', 'ssh', 'ping'],
    'timemark': ['10:00AM', '10:05AM', '10:10AM', '10:15AM']
}
df = pd.DataFrame(data)

# 按source→destination→application分组,聚合timemark(收集所有时间戳)
grouped_df = df.groupby(['source', 'destination', 'application'])['timemark'].agg(list).reset_index()

步骤2:构建树结构

这里推荐用treelib库来快速构建层级树,它能方便地创建节点、管理父子关系,还支持文本和图形化输出。

先安装treelib:

pip install treelib

然后编写构建树的代码:

from treelib import Tree

# 创建总根节点(可选,用来统管所有source节点)
tree = Tree()
tree.create_node("Network Traffic", "root")

# 遍历分组后的数据,逐层添加节点
for idx, row in grouped_df.iterrows():
    source = row['source']
    dest = row['destination']
    app = row['application']
    times = ', '.join(row['timemark'])
    
    # 检查source节点是否存在,不存在则创建
    if not tree.contains(source):
        tree.create_node(source, source, parent="root")
    
    # 检查destination节点是否属于当前source,不存在则创建
    dest_node_id = f"{source}_{dest}"
    if not tree.contains(dest_node_id):
        tree.create_node(dest, dest_node_id, parent=source)
    
    # 添加application节点,附带时间戳信息
    app_node_id = f"{dest_node_id}_{app}"
    tree.create_node(f"{app} (times: {times})", app_node_id, parent=dest_node_id)

# 先打印文本形式的树,快速验证结构
tree.show()

运行后会输出清晰的文本树结构,比如:

Network Traffic
├── 192.168.1.1
│   ├── 192.168.1.200
│   │   ├── ping (times: 10:00AM)
│   │   └── http (times: 10:05AM)
│   └── 192.168.1.300
│       └── ping (times: 10:15AM)
└── 192.168.1.2
    └── 192.168.1.100
        └── ssh (times: 10:10AM)

步骤3:图形化树状图展示

如果需要可视化的树状图,可以用以下两种方法:

方法1:用treelib导出为图片(需安装graphviz)

先安装依赖:

pip install graphviz

然后导出并生成图片:

# 导出为dot格式文件
tree.to_graphviz("network_tree.dot")
# 把dot文件转成png图片
from graphviz import render
render('dot', 'png', 'network_tree.dot')

执行后会生成network_tree.png,展示标准的树形层级图。

方法2:用NetworkX + Matplotlib绘制交互式树

如果更习惯用matplotlib,可以用NetworkX构建图结构,再绘制树形布局:

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()

# 逐层添加节点和边
for idx, row in grouped_df.iterrows():
    source = row['source']
    dest = row['destination']
    app = row['application']
    app_label = f"{app}\n({', '.join(row['timemark'])})"
    
    # 添加总根节点
    if 'root' not in G.nodes:
        G.add_node('root', label='Network Traffic')
    G.add_edge('root', source)
    
    # 添加source到dest的边
    G.add_edge(source, dest)
    
    # 添加dest到application的边
    G.add_edge(dest, app_label)

# 设置树形布局(用graphviz的dot布局)
pos = nx.nx_agraph.graphviz_layout(G, prog='dot')

# 绘制节点和边
nx.draw(G, pos, with_labels=True, node_size=3500, node_color='lightblue', font_size=8, arrows=True)
plt.title("Network Communication Tree")
plt.show()

方法3:交互式树形图(Plotly)

如果需要可交互的探索式树图(比如点击节点展开/折叠),可以用Plotly的treemap或sunburst:

import plotly.express as px

# 构造Plotly需要的层级路径数据
plot_df = grouped_df.copy()
plot_df['count'] = plot_df['timemark'].apply(len)  # 统计每个通信组合的次数
fig = px.treemap(plot_df, 
                 path=['source', 'destination', 'application'], 
                 values='count',
                 hover_data={'timemark': plot_df['timemark'].apply(', '.join)})
fig.update_layout(title="Network Communication Treemap")
fig.show()

注意事项

  • 如果数据量很大,树状图会拥挤,建议过滤低频通信对,或者合并重复节点。
  • timemark可以按需处理:比如只保留最新/最早时间,或者统计通信次数,作为节点标签的一部分。

内容的提问来源于stack exchange,提问作者Pablo Ibañez Matía

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:31:59