【问题标题】:What is the purpose of using StringIO in DecisionTree在DecisionTree中使用StringIO的目的是什么
【发布时间】:2019-09-17 14:03:04
【问题描述】:

我正在写一个决策树,下面的代码是完整代码的一部分:

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的目的是什么?

【问题讨论】:

    标签: python scikit-learn decision-tree stringio


    【解决方案1】:

    Python 不是我的主要语言,但我认为您的问题的答案很简单,不需要大量研究。

    这里使用StringIO 来维护输入/输出文本流。您的函数显示树,但是要做到这一点,它需要一种方法来做到这一点,某种数据传输高速公路。

    这里f = io.StringIO() 正在初始化数据流。之后,您可以随意使用它,在这种特殊情况下:

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

    这里:out_file=f 使用f = io.StringIO(); 之前的初始化将数据导出到流。由于 StringIO 是内存中的文本文件,因此您基本上将数据放在流对象中以供进一步使用。由于您不必将数据写入 .dot 文件,而是暂时保存它。(只要您的流在使用中,临时意味着)

    More about this particular case

    1. pydotplus.graph_from_dot_data(f.getvalue()).write_png(path)

    这里:f.getvalue() 您从 .dot 数据生成图表。在最基本的使用中,您应该确保之前生成的数据将存储在其中的 .dot 文件的路径,但您不必这样做!这就是诀窍,您的数据仍在您事先创建和填充的流对象中!所以现在你所要做的就是直接将它指向这个函数,它将使用该数据生成你的图形图像并将其保存为 .png 文件。

    系统文件和程序之间的通信可以通过多种方式建立,但通常您使用流。您在一开始就初始化流,使用它然后关闭。每个std::coutstd:err(我的主要语言参考,对不起那个非python 示例)都是那个流。 Stream 允许您维护程序和指定 tagret(例如控制台,或在这种情况下为文件)之间的数据交换,但是您也可以将其用作临时存储空间,在这种特殊情况下,这将加快图像生成过程,因为您不需要真的必须将数据写入文件并将其加载到文件中。多亏了这一点,您所要做的就是按照其他函数接受的顺序将数据写入流,然后使用相同的流读取该数据以生成图像。

    More about StringIO

    【讨论】:

    • 字符串 IO 是人类可读的,因为它使用 unicode。它必须转换为字节 IO 才能被计算机读取。那么代码作者为什么不使用字节IO呢?而他为什么不给字符串io赋值呢?
    • 您的目标数据接收者需要.dot 格式,这与二进制格式相差甚远,为什么以及根据您认为需要将其转换为ByteIO 的原因?我不明白你关于为StringIO 分配任何值的问题的第二部分我相信我在上面很好地解释了这个模块背后的想法。
    • 我是 python 的新手,我最近才掌握了字符串 IO 和字节 IO 背后的想法,这让我想到了 ASCII、UTF 和 Unicode。字符串 IO 使用 Unicode 字符串,字节 IO 使用字节字符串。所以基本上 StringIO 是用于文本的。当您在内存中有要视为来自或去往文件的文本时,您可以使用它。 BytesIO 用于字节。它在与 StringIO 类似的上下文中使用,除了使用字节而不是文本。现在我开始理解你上面解释的想法了
    • 相当新也没什么不好。字符串概念在许多语言中都很常见,一旦你用任何其他语言轻松理解它,你就会得到它。 @Hichem BOUSSETTA 为您提供了解决同一问题的几种不同方法的好例子。重点阅读pydotplus文档及其功能。如果函数需要 .dot 文件或 .dot 数据,这正是您必须提供的。如果您将其提供为stringstream,则带有.dot 数据的实际文件或只是变量(`graph_from_dot_data` 案例)取决于您。
    【解决方案2】:

    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)
    

    【讨论】:

    • 你能写出使用普通文本文件的代码吗?
    • 我正在研究 .dot 格式,因为我是 python 新手。当我有想法时会回复你
    • 能否详细说明将 out_file 保留为 none 的影响。
    • 影响只是 export_graphviz() 不会写入文件,而是将数据作为字符串返回。我认为这个解决方案相当于使用stringIO,因为数据保存在内存中。
    • 所以在所有三种情况下,即: 1- 将数据存储在 StringIO 2- 存储在常规文本文件中 3- 并存储在点文件的字符串内容中。数据存储为 DOT 数据。如果我错了,请纠正我
    猜你喜欢
    • 2012-01-19
    • 2011-12-21
    • 2010-11-15
    • 2020-04-30
    • 2020-07-13
    • 1970-01-01
    • 2015-04-08
    • 2012-09-17
    • 2019-08-06
    相关资源
    最近更新 更多