Язык Julia: перенаправление stdout не влияет на каждый println // Как извлечь значение из stdout

Моя первоначальная цель состояла в том, чтобы выполнить ttest и получить pvalue. Я использовал OneSampleTTest, который выглядел многообещающе, но результаты закончились. в stdout следующим образом:

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-тестов и использовать файл для хранения результатов и перечитывать их каждый раз, когда это звучит ужасно.


person grimbar    schedule 20.10.2019    source источник


Ответы (2)


Вызов OneSampleTTest на самом деле ничего не печатает. Если вы поставите точку с запятой в конце строки, вы увидите, что вывод не отображается.

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

julia>

Что делает OneSampleTTest(), так это возвращает значение типа OneSampleTTest. Он даже не выполняет тест, а просто создает тестовый объект. Поскольку вы не поставили точку с запятой в конце, Джулия вызовет метод Base.show, чтобы написать информативный текст об этом значении в текущий выходной поток. OneSampleTTest — это подтип HypothesisTest, который расширяет метод 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 на вашем тестовый объект вычислит и вернет 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
person hckr    schedule 20.10.2019
comment
Отличный ответ! Потрясающей помощью было не только исправление моего ошибочного предположения о том, что происходит println, и как получить строковое представление возвращаемого вместо этого объекта, но и указание на простое решение вызова pvalue(test). Я чувствую, что документация OneSampleTTest могла бы привести несколько примеров того, как извлечь все, что имеет отношение к его результату. - person grimbar; 21.10.2019

Я бы посоветовал довериться Джулии и вашей ОС, чтобы делать такие вещи быстро, и пытаться оптимизировать только после того, как вы столкнетесь с узким местом.

Следующий код печатает p-значения в виде строк в текстовый файл без какого-либо перенаправления stdout и работает быстро. Для миллиона итераций требуется 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/, чтобы узнать, подход к обработке данных может быть улучшен.

person laborg    schedule 20.10.2019