使用Graphviz读取CSV构建决策树时的索引错误排查
解决Pandas索引错误及决策树可视化代码修复
问题背景
读取CSV文件构建决策树节点,并使用Graphviz实现可视化,运行代码时卡在第27行,两次修改索引代码均触发报错:
- 首次使用
row = df.index[index],触发IndexError:索引类型不合法 - 修改为
row = df.index(int[index]),触发TypeError:类型对象不可下标访问
报错原因分析
- 第一次报错原因:
df[::-1].iterrows()返回的index已经是DataFrame的索引值(即CSV中ID列的值),无需再通过df.index[index]取值。这里错误地将迭代变量index当成了位置索引,导致索引类型不匹配。 - 第二次报错原因:语法错误,
int是Python内置类型,不能用int[index]的方式调用,即使写成int(index)也完全多余——因为index本身就是ID的数值/标识。
代码修复方案
- 移除多余的
row = df.index[...]行,直接使用iterrows()返回的index和row数据 - 简化NaN值判断逻辑,使用Pandas内置的
isna()方法,替代isinstance+math.isnan的复杂判断 - 修正Node创建与nodes列表插入的语法错误(原代码用逗号导致语句变成元组赋值,需拆分为两行)
- 优化图片保存函数,避免临时文件操作的冗余步骤
完整修正代码
import graphviz import pandas import os def save_graph_as_jpg(graph, filename): # 直接使用render方法生成图片,无需手动处理dot文件 graph.render(filename, format="jpg", cleanup=True) class Node: def __init__(self, data, left=None, right=None): self.left = left self.right = right self.data = data # 读取CSV,ID列为索引 df = pandas.read_csv('decisiontree.csv', index_col="ID") print(df.to_string()) print(df.info()) nodes = [] nodeMap = {None: None} # 逆序迭代行(从叶子节点到根节点构建) for node_id, row in df[::-1].iterrows(): # 处理子节点ID的NaN值,转为None left_child_id = row[3] if not pandas.isna(row[3]) else None right_child_id = row[2] if not pandas.isna(row[2]) else None # 创建节点并加入映射表 nodeMap[node_id] = Node(row[1], nodeMap[left_child_id], nodeMap[right_child_id]) nodes.insert(0, node_id) # 构建Graphviz图 graph = graphviz.Digraph('structs', node_attr={'shape': 'plaintext', 'ordering':'out'}) for node_id in nodes: node = nodeMap[node_id] if node.left: graph.edge(node.data, node.left.data) if node.right: graph.edge(node.data, node.right.data) # 保存为JPG save_graph_as_jpg(graph, "Decisiontree")
关键修正点说明
- 迭代逻辑:
iterrows()返回的node_id就是CSV中的ID值,直接用来定位行数据和节点ID - NaN处理:
pandas.isna()能直接识别缺失值,无需额外判断类型 - 语法修复:将原代码中
nodeMap[...] = ..., nodes.insert(...)拆分为两行,避免元组赋值错误 - 函数优化:
graph.render的cleanup=True参数会自动删除生成的dot文件,无需手动删除临时文件
内容的提问来源于stack exchange,提问作者jls0811
相关产品推荐
相关产品推荐

