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

使用Graphviz读取CSV构建决策树时的索引错误排查

解决Pandas索引错误及决策树可视化代码修复

问题背景

读取CSV文件构建决策树节点,并使用Graphviz实现可视化,运行代码时卡在第27行,两次修改索引代码均触发报错:

  • 首次使用row = df.index[index],触发IndexError:索引类型不合法
  • 修改为row = df.index(int[index]),触发TypeError:类型对象不可下标访问

报错原因分析

  1. 第一次报错原因:df[::-1].iterrows()返回的index已经是DataFrame的索引值(即CSV中ID列的值),无需再通过df.index[index]取值。这里错误地将迭代变量index当成了位置索引,导致索引类型不匹配。
  2. 第二次报错原因:语法错误,int是Python内置类型,不能用int[index]的方式调用,即使写成int(index)也完全多余——因为index本身就是ID的数值/标识。

代码修复方案

  1. 移除多余的row = df.index[...]行,直接使用iterrows()返回的index和row数据
  2. 简化NaN值判断逻辑,使用Pandas内置的isna()方法,替代isinstance+math.isnan的复杂判断
  3. 修正Node创建与nodes列表插入的语法错误(原代码用逗号导致语句变成元组赋值,需拆分为两行)
  4. 优化图片保存函数,避免临时文件操作的冗余步骤

完整修正代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 16:25:26