Julia 语言:重定向 stdout 不会影响每个 println // 如何从 stdout 中提取值

Julia language: Redirecting stdout does not affect every println // How to extract value from stdout

我最初的目标是执行测试并获得 pvalue。 我使用了 OneSampleTTest 看起来很有希望,但结果在标准输出中是这样的:

julia> OneSampleTTest([1,2,3,4,5],3.1)
One sample t-test
-----------------
Population details:
    parameter of interest:   Mean
    value under h_0:         3.1
    point estimate:          3.0
    95% confidence interval: (1.0368, 4.9632)

Test summary:
    outcome with 95% confidence: fail to reject h_0
    two-sided p-value:           0.8944

Details:
    number of observations:   5
    t-statistic:              -0.14142135623730961
    degrees of freedom:       4
    empirical standard error: 0.7071067811865476

我想得到这个值:

two-sided p-value: 0.8944

为了重定向标准输出,我在我们的网站上找到了 。但似乎 OneSampleTTest 的输出不受此影响。

julia> using HypothesisTests

julia> original_stdout = stdout
Base.TTY(RawFD(0x0000001b) open, 0 bytes waiting)

julia> (rd, wr) = redirect_stdout()
(Base.PipeEndpoint(RawFD(0x00000020) open, 0 bytes waiting), Base.PipeEndpoint(RawFD(0x00000025) open, 0 bytes waiting))

julia> println("test")

julia> s = readline(rd)
"test"

julia> s == "test"
true

julia> OneSampleTTest([1,2,3,4,5],3.1)
One sample t-test
-----------------
Population details:
    parameter of interest:   Mean
    value under h_0:         3.1
    point estimate:          3.0
    95% confidence interval: (1.0368, 4.9632)

Test summary:
    outcome with 95% confidence: fail to reject h_0
    two-sided p-value:           0.8944

Details:
    number of observations:   5
    t-statistic:              -0.14142135623730961
    degrees of freedom:       4
    empirical standard error: 0.7071067811865476


julia> 

如果另一个 s = readline(rd) 它会卡住,因为 rd 中没有任何内容。 (我假设)

我解决这个问题的唯一其他想法是尝试将测试结果写入文件并再次解析该文件。但我想做数百万次 t 检验并使用一个文件来存储结果并每次都重新读取它们听起来像是一项糟糕的性能工作。

我建议相信 Julia 和你的 OS 可以快速完成这些事情,并且只在遇到瓶颈后才尝试优化。

以下代码将 p 值作为 字符串 打印到文本文件中,无需任何类型的标准输出重定向,而且速度很快。一百万次迭代需要 2.5 秒.

 open("pvalues.txt","w") do io
    for i in 1:1000000 

        # do the test
        test = might be a better place.OneSampleTTest(rand(Int64,5),3.1)

        # transform only the pvalue of the test to a string an write it
        # take note of the function "pvalue", which extract, well, the p-value!
        write(io,string(pvalue(test),"\n"))

    end
end

您也可以将您的讨论带到 https://discourse.julialang.org/ 以了解您处理数据的总体方法是否可以改进。

OneSampleTTest 的调用 而不是 实际上打印任何东西。如果你在行尾放一个分号,你会看到没有输出显示。

julia> OneSampleTTest([1,2,3,4,5],3.1);

julia>

OneSampleTTest() 所做的是 return 类型 OneSampleTTest 的值。它甚至不做测试,只是创建一个测试对象。由于您没有在末尾放置分号,Julia 将调用方法 Base.show 将有关此值的信息文本写入当前输出流。 OneSampleTTestHypothesisTest 的子类型,它扩展了 Base.show 方法来写入您在控制台上看到的输出。

如果您出于某种原因需要存储 show 的输出,您可以使用 Base.repr,它将 show 的输出作为 String .

julia> result = repr(OneSampleTTest([1,2,3,4,5],3.1));

julia> result
"One sample t-test\n-----------------\nPopulation details:\n    parameter of interest:   Mean\n    value under h_0:         3.1\n    point estimate:          3.0\n    95% confidence interval: (1.0368, 4.9632)\n\nTest summary:\n    outcome with 95% confidence: fail to reject h_0\n    two-sided p-value:           0.8944\n\nDetails:\n    number of observations:   5\n    t-statistic:              -0.14142135623730961\n    degrees of freedom:       4\n    empirical standard error: 0.7071067811865476\n"

请注意,您不需要通过 解析文本来提取 p 值 OneSampleTTest 实现 pvalue 方法,只需在测试对象上使用 pvalue 即可计算和 return p 值。

julia> test = OneSampleTTest([1,2,3,4,5],3.1); # this only creates an object, does not compute p-value

julia> pvalue(test) # computes and `show`s the value