我正在编写决策树,以下代码是完整代码的一部分:
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的目的是什么吗?
答案 0 :(得分:1)
Python不是我的主要语言,但是我认为您的问题的答案非常简单,不需要大量研究。
StringIO在这里用于维护输入/输出文本流。您的函数显示树,但是为此,它需要一种实现方法,某种数据传输高速公路。
这里f = io.StringIO()
正在初始化数据流。之后,在这种特殊情况下,您可以随意使用它:
export_graphviz(tree, out_file=f, feature_names=features)
此处:out_file=f
使用f = io.StringIO();
之前的初始化数据将数据导出到流中。由于StringIO是内存中的文本文件,因此您基本上将数据放在流对象中以备将来使用。因此,您不必将数据写到 .dot 文件中,而只需将其临时保留。(并且临时意味着只要您的流处于使用状态)
More about this particular case
pydotplus.graph_from_dot_data(f.getvalue()).write_png(path)
在这里:f.getvalue()
是从 .dot 数据生成图形的。在最基本的用法中,应确保将 .dot 文件的路径存储在其中,以前存储的数据将存储在该文件中,但您不必这样做!这就是诀窍,您的数据仍在您事先创建并填充的流对象中!因此,现在您要做的就是直接将其定向到此函数,该函数将使用该数据生成图形图像并将其另存为 .png 文件。
可以通过多种方式建立系统文件与程序之间的通信,但通常使用流。您在一开始就初始化流,使用它然后关闭。每个std::cout
或std:err
(我的主要语言参考,对于该非python示例都很抱歉)就是该流。 Stream允许您维护程序与指定的tagret(例如控制台,在这种情况下为文件)之间的数据交换,但是您也可以将其用作临时存储空间,在这种情况下,您可以不使用它来加快图像生成过程确实必须将数据写入文件并加载到文件中。要做的全部工作就是按照其他函数可以接受的顺序将数据写入流,然后使用相同的流读取该数据以生成图像。
答案 1 :(得分:0)
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)