#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. На самом деле я сначала отвечу здесь, отредактировав свой ответ 🙂