在决策树中使用StringIO的目的是什么?

3
我正在编写一棵决策树,以下代码是完整代码的一部分:
def show_tree(tree, features, path):
    f = io.StringIO()
    export_graphviz(tree, out_file=f, feature_names=features)
    pydotplus.graph_from_dot_data(f.getvalue()).write_png(path)
    img = misc.imread(path)
    plt.rcParams['figure.figsize'] = (20,20)
    plt.imshow(img)

请问在这里使用StringIO的目的是什么?

2个回答

1

StringIO代表一个内存中的文本文件。它可以像任何文本文件一样使用,因此您可以从中写入/读取。访问速度比常规文件快,因为stringio缓冲区在内存中管理,但另一方面它不会持久保存在磁盘上。

在您提供的示例中,您也可以使用常规文本文件。

这是一个使用常规点文本文件的示例:

def show_tree(tree, features, path):
    f = 'tree.dot'
    export_graphviz(tree, out_file=f, feature_names=features)
    pydotplus.graph_from_dot_file(f).write_png(path)
    img = misc.imread(path)
    plt.rcParams['figure.figsize'] = (20,20)
    plt.imshow(img)

这是另一个示例,不需要文件和StringIO,只需使用export_graphviz()导出的点文件的字符串内容即可。
def show_tree(tree, features, path):
    dot_data = export_graphviz(tree, out_file=None, feature_names=features)
    pydotplus.graph_from_dot_data(dot_data).write_png(path)
    img = misc.imread(path)
    plt.rcParams['figure.figsize'] = (20,20)
    plt.imshow(img)

请问您能否编写使用普通文本文件的代码? - Hasham Beyg
我正在研究.dot格式,因为我是Python的新手。当我有了想法,我会回复你的。 - Hasham Beyg
请您详细说明将 out_file 参数设为 none 的影响。 - Hasham Beyg
影响只是export_graphviz()不会写入文件,而是将数据作为字符串返回。我认为这个解决方案相当于使用stringIO,因为数据保存在内存中。 - Hichem BOUSSETTA
所以在这三种情况下,即: 1- 将数据存储在StringIO中 2- 存储在常规文本文件中 3- 并将其存储在DOT文件的字符串内容中。数据被存储为DOT数据。如果我错了,请纠正我。 - Hasham Beyg
这可能是一个愚蠢的问题,但我还是想问一下。 在以下代码中,写(f)和(f.getvalue)有什么区别:pydotplus.graph_from_dot_file(f).write_png(path)pydotplus.graph_from_dot_data(f.getvalue()).write_png(path) - Hasham Beyg

1

Python不是我的主要语言,但我认为你的问题的答案非常简单,不需要太多研究。

StringIO在这里用于维护输入/输出文本流。您的函数展示树,但为了做到这一点,它需要一种方法来实现,一种数据传输高速公路。

这里f = io.StringIO()初始化了数据流。之后,您可以自由使用它,特别是在这种情况下:

  1. export_graphviz(tree, out_file=f, feature_names=features)

这里:out_file=f您将数据导出到已经初始化的流中f = io.StringIO();。由于StringIO是内存文本文件,因此您基本上将数据放在流对象中以供进一步使用。感谢这一点,您无需将数据写入.dot文件,而是暂时将其保留。(“暂时”意味着只要您的流正在使用)

有关此特定情况的更多信息

  1. pydotplus.graph_from_dot_data(f.getvalue()).write_png(path)
在这里:f.getvalue(),你可以从.dot数据生成你的图表。在最基本的用法中,你应该确保路径指向先前生成的数据存储在其中的.dot文件,但是你不必这样做!这就是诀窍,你的数据仍然在之前创建并填充的流对象中!现在你所要做的就是将它直接定向到这个函数,该函数将使用该数据生成你的图像,并将其保存为.png文件。
系统文件和你的程序之间的通信可以通过多种方式建立,但通常你使用流。你在最开始初始化流,在使用它,然后关闭。每个std::coutstd:err(我的主要语言参考,抱歉提供了非Python示例)都是那个流。流允许你在你的程序和指定目标(例如控制台,或在这种情况下的文件)之间维护数据交换,但在这种特殊情况下,你也可以将其用作临时存储空间,这将加速图像生成过程,因为你不必真正将数据写入和加载到文件中。你所要做的就是按照其他函数将接受的顺序将数据写入流中,然后使用完全相同的流来读取该数据以进行图像生成。

更多关于StringIO的信息


字符串IO是人类可读的,因为它使用Unicode。必须将其转换为字节IO才能使计算机读取。那么,为什么代码的作者没有使用字节IO呢?而且,他为什么没有给字符串IO分配任何值? - Hasham Beyg
你的目标数据接收方需要 .dot 格式,这与二进制格式相差甚远,你认为它需要转换为 ByteIO 的原因是什么?我不理解你问题的第二部分,关于给 StringIO 分配任何值的部分。我相信我在上面已经很好地解释了这个模块背后的思想。 - PStarczewski
我在Python方面还比较新,最近才掌握了String IO和Bytes IO的概念,这让我了解到ASCII、UTF和Unicode。String IO使用Unicode字符串,而Bytes IO使用字节字符串。因此,StringIO用于文本。当您在内存中有要视为来自文件或要发送到文件的文本时,可以使用它。BytesIO用于字节。它与StringIO在类似的上下文中使用,只不过是用字节代替文本。现在我开始理解您上面解释的概念了。 - Hasham Beyg
成为新手并没有什么不好。字符串概念在许多编程语言中都很常见,一旦掌握,您就可以轻松理解其他任何语言中的字符串概念。@Hichem BOUSSETTA为同一个问题提供了几种不同的方法,这是很好的例子。专注于阅读pydotplus文档及其函数。如果函数需要.dot文件或.dot数据,则必须提供它。如果您将其作为stringstream、实际文件带有.dot数据或只是变量(graph_from_dot_data情况)提供,完全由您决定。 - PStarczewski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接