Я пытаюсь понять, как собрать/гистограммировать массив данных в Джулии. У меня есть массив единиц из пакета Unitful.jl
, и я хочу использовать Histogram
из 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
[ОТРЕДАКТИРОВАНО, потому что я неправильно понял вопрос]
Вы хотите построить гистограмму данных? Если да, то вместо StatsBase.jl я бы использовал функцию histogram
графического пакета, такого как Plots.jl. Например, чтобы объединить графики из Plots.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
О, я вижу, я также вижу, что вы опубликовали проблему на Unitful.jl. Я тогда туда вклинюсь :)
На самом деле я сначала отвечу здесь, отредактировав свой ответ :)
это не то, что я хочу сделать. Я хочу собирать данные или гистограммы с единицами измерения. Итак, скажем, у меня есть массив из 1000 измерений в МГц, которые имеют диапазон от 40 МГц до 1000 МГц. Я хочу собрать данные, чтобы понять их распределение. Я не уверен, как
StatsBase
используетlog10
.. но я просто пытался заставить это работать. может быть, мне просто нужно изменить полученную гистограмму и изменить ее края на единицы или что-то в этом роде..