我从 .mat 文件(MATLAB 格式)导入了一堆数据,它们以字典的形式出现,但使用它们有点烦人,所以我想将其传递为结构体。我知道我能做到:
using MAT
struct model
trans
means
vars
end
vars = matread("data.mat")
hmm1=model(vars["hmm1"]["trans"],vars["hmm1"]["means"],vars["hmm1"]["vars"])
有没有办法不用输入字典的每个键就能做到这一点?
可能无法避免直接访问字典的相关键。但是,您可以通过创建一个接受
Model
的自定义 Dict
构造函数来稍微简化您的生活:
using MAT
struct Model
trans
means
vars
end
function Model(d::Dict)
h = d["hmm1"]
Model(h["trans"], h["means"], h["vars"])
end
d = matread("data.mat")
Model(d)
如果您只担心点访问语法 à la
hmm1.means
,您可以使用 NamedTuple
:
julia> vars = Dict("hmm1"=>Dict("trans"=>1, "means"=>2, "vars"=>3)) ;
julia> hmm1 = (; (Symbol(k) => v for (k,v) in vars["hmm1"])...)
(trans = 1, vars = 3, means = 2)
julia> hmm1.means
2
(取自并改编自 Julia 话语:如何从字典中创建命名元组?。)
我遇到了同样的问题:使用 MAT.jl 加载 Matlab 文件,该文件返回嵌套字典。我没有将字典转换为(嵌套)结构,而是编写了以下函数来递归搜索字典中的任何(嵌套)路径。
function superget(fault::Dict{String, Any}, path)
# Use 'get' recursively to find nested path in fault
if !occursin("/", path) && !occursin(".", path)
return get(fault, path, missing)
elseif occursin("/", path)
splitpath = split(path, "/")
superget(get(fault, popfirst!(splitpath), missing), join(splitpath, "/"))
elseif occursin(".", path)
splitpath = split(path, ".")
superget(get(fault, popfirst!(splitpath), missing), join(splitpath, "."))
end
end
使用示例
using MAT
vars = MAT.matread(path2file)
# defining path with '/'
range_x = superget(vars, "path/to/parameter/range_x")
# or use '.'
range_x = superget(vars, "path.to.parameter.range_x")