Как составить гистограмму единичных единиц измерения в Julia?

#julia #composition

#джулия #композиция

Вопрос:

Я пытаюсь выяснить, как создать / гистограмму массива данных в Julia. У меня есть массив единиц измерения из Unitful.jl пакета, и я хочу использовать Histogram from StatsBase для объединения данных. Первой ошибкой, которую я получил, была ошибка, в которой говорилось, что для использования не было методов log10 Unitful.FreeUnits , поэтому я написал один. Теперь я получаю размерную ошибку. Я думал, что Unitful будет работать только с другими вещами.. думаю, нет. Вот где я нахожусь.

 using Unitful
using StatsBase

data = [rand()*100*1u"MHz" for x in 1:10000]

function Base.log10(x::Quantity{})
    u = unit(x)
    return log10(x.val)u
end

# eventually I want to define my bin width manually.. but this is a start.
fit(Histogram, data)

 

ОШИБКА

 ERROR: DimensionError: 0.0 and 0.8237981449864736 MHz are not dimensionally compatible.
Stacktrace:
 [1] _lt at /home/mcamp/.julia/packages/Unitful/1t88N/src/quantities.jl:274 [inlined]
 [2] <(::Quantity{Float64,NoDims,Unitful.FreeUnits{(),NoDims,nothing}}, ::Quantity{Float64,𝐓^-1,Unitful.FreeUnits{(MHz,),𝐓^-1,nothing}}) at /home/mcamp/.julia/packages/Unitful/1t88N/src/quantities.jl:264
 [3] <(::Int64, ::Quantity{Float64,𝐓^-1,Unitful.FreeUnits{(MHz,),𝐓^-1,nothing}}) at /home/mcamp/.julia/packages/Unitful/1t88N/src/quantities.jl:266
 [4] <=(::Int64, ::Quantity{Float64,𝐓^-1,Unitful.FreeUnits{(MHz,),𝐓^-1,nothing}}) at ./operators.jl:326
 [5] >=(::Quantity{Float64,𝐓^-1,Unitful.FreeUnits{(MHz,),𝐓^-1,nothing}}, ::Int64) at ./operators.jl:350
 [6] histrange(::Quantity{Float64,𝐓^-1,Unitful.FreeUnits{(MHz,),𝐓^-1,nothing}}, ::Quantity{Float64,𝐓^-1,Unitful.FreeUnits{(MHz,),𝐓^-1,nothing}}, ::Int64, ::Symbol) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:51
 [7] histrange(::Array{Quantity{Float64,𝐓^-1,Unitful.FreeUnits{(MHz,),𝐓^-1,nothing}},1}, ::Int64, ::Symbol) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:39
 [8] (::StatsBase.var"#127#128"{Symbol})(::Array{Quantity{Float64,𝐓^-1,Unitful.FreeUnits{(MHz,),𝐓^-1,nothing}},1}, ::Int64) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:103
 [9] map(::StatsBase.var"#127#128"{Symbol}, ::Tuple{Array{Quantity{Float64,𝐓^-1,Unitful.FreeUnits{(MHz,),𝐓^-1,nothing}},1}}, ::Tuple{Int64}) at ./tuple.jl:176
 [10] histrange(::Tuple{Array{Quantity{Float64,𝐓^-1,Unitful.FreeUnits{(MHz,),𝐓^-1,nothing}},1}}, ::Tuple{Int64}, ::Symbol) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:102
 [11] fit(::Type{Histogram{Int64,N,E} where E where N}, ::Tuple{Array{Quantity{Float64,𝐓^-1,Unitful.FreeUnits{(MHz,),𝐓^-1,nothing}},1}}; closed::Symbol, nbins::Int64) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:332
 [12] fit(::Type{Histogram{Int64,N,E} where E where N}, ::Array{Quantity{Float64,𝐓^-1,Unitful.FreeUnits{(MHz,),𝐓^-1,nothing}},1}; closed::Symbol, nbins::Int64) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:276
 [13] fit(::Type{Histogram{Int64,N,E} where E where N}, ::Array{Quantity{Float64,𝐓^-1,Unitful.FreeUnits{(MHz,),𝐓^-1,nothing}},1}) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:276
 [14] fit(::Type{Histogram}, ::Array{Quantity{Float64,𝐓^-1,Unitful.FreeUnits{(MHz,),𝐓^-1,nothing}},1}; kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:383
 [15] fit(::Type{Histogram}, ::Array{Quantity{Float64,𝐓^-1,Unitful.FreeUnits{(MHz,),𝐓^-1,nothing}},1}) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:383
 [16] top-level scope at REPL[183]:1
 [17] run_repl(::REPL.AbstractREPL, ::Any) at /build/julia/src/julia-1.5.3/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:288
 

Ответ №1:

[ОТРЕДАКТИРОВАНО, потому что я неправильно понял вопрос]

Вы хотите построить гистограмму данных? Если да, то вместо StatsBase.jl я бы использовал histogram функцию пакета построения графиков, например Plots.jl. Например, для объединения участков из участков.jl с единицами измерения из Unitful.jl вы можете использовать пакет UnitfulRecipes.jl. Посмотрите на это MWE, это может быть то, что вам нужно:

 using Unitful: MHz
using Plots
using UnitfulRecipes
data = 100 * exp.(randn(10000)) * MHz
histogram(data)
 

будет выводить

гистограмма данных с единицами измерения


[ПЕРЕД РЕДАКТИРОВАНИЕМ]

Я не думаю, что математически или физически имеет смысл брать логарифм безразмерной переменной (т. Е. Переменной с единицей измерения). То есть ваше переопределение log10 не является хорошей идеей, ИМХО. Вместо этого я бы безразмерно обработал данные перед тем, как вести журнал, с помощью чего-то похожего на

 using Unitful: MHz
using StatsBase
data = 100 * rand(10000) * MHz
data_nodim = log10.(data / MHz) # <- this is valid
fit(Histogram, data_nodim)      # <- this is valid too
 

Комментарии:

1. это не то, что я собираюсь делать.. Я хочу записать данные в ячейку или гистограмму с единицами измерения. Допустим, у меня есть массив из 1000 измерений в МГц, которые имеют диапазон от 40 МГц до 1000 МГц. Я хочу объединить данные, чтобы получить представление о их распределении. Я не уверен, как StatsBase это использовать log10 .. но я просто пытался как-то заставить это работать. может быть, мне просто нужно изменить созданную гистограмму и изменить ее края на единицы измерения или что-то в этом роде..

2. О, я вижу, я также вижу, что вы опубликовали выпуск на Unitful.jl . Тогда я включусь в это 🙂

3. На самом деле я сначала отвечу здесь, отредактировав свой ответ 🙂