如何在 Julia 中检索数组的数组?
How do I retrieve an array of arrays of arrays in Julia?
我是 Julia 新人,所以请不要评判我(哈哈)
这是我的情况:我需要保存几个 2x2x2 矩阵,其元素是 4 个元素的向量,但现在当我尝试从文件中检索它们时,我不能!!!
这是我做的:
为了创建这些矩阵,我创建了这个函数
function InitialConf(L_=2,S_=2,T_=2,Dim_=4)
Conf_=Array{Array{Float64,1}}(L_,S_,T_)
for i_ = 1:L_, j_=1:S_,k_=1:T_
Conf_[i_,j_,k_]=RanUniVec(Dim_)
end
return Conf_
end
其中 RanUniVec(Dim_) 是创建这些具有特殊特征的 4 维向量的函数,这些特征对于本次讨论并不重要:
function RanUniVec(Dim_)
vector_=Array{Float64}(Dim_)
while true
for i_ in 1:Dim_
vector_[i_]=UniformRand(-1,1)
end
if norm(vector_)<1 && norm(vector_)>0.5
break
end
end
vector_=normalize(vector_) # 2-norm
return vector_
end
function UniformRand(a_,b_)
rand_=(b_-a_)*rand()+a_
return rand_
end
我需要其中两个矩阵(例如)所以我做了下一个:
States=[]
Conf1=InitialConf()
Conf2=InitialConf()
push!(States,Conf1)
push!(States,Conf2)
f=open("Info.txt","w") do f
write(f,"$States")
end
这使得我的信息所在的 Info.txt 文件,但是当我再次尝试从中获取 States 数组时这个文件,Julia 告诉我它不能
f=readlines("Info.txt")
States=parse(f)
ERROR: MethodError: no method matching parse(::Array{String,1})
Closest candidates are:
parse(::Type{IPv4}, ::AbstractString) at socket.jl:167
parse(::Type{IPv6}, ::AbstractString) at socket.jl:218
parse(::Type{DateTime}, ::AbstractString, ::DateFormat{Symbol("yyyy-mm-dd\THH:MM:SS.s"),Tuple{Base.Dates.DatePart{'y'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'m'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'d'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'H'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'M'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'S'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'s'}}}) at dates/parse.jl:202
...
你知道我怎样才能再次获得我的 State 数组吗?
一般来说,您应该使用长 运行 评论中 Colin 的推荐。如果您确实已经生成了这些文本文件,那么您可以执行以下操作。我将使用一个较小的示例。
假设您的原始数组由两个 2x2x2 数组组成。这是我将使用的示例:
julia> z
2-element Array{Array{Int64,3},1}:
[1 2; 3 4]
[10 20; 30 40]
[1 2; 3 4]
[10 20; 30 40]
julia> z[1]
2×2×2 Array{Int64,3}:
[:, :, 1] =
1 2
3 4
[:, :, 2] =
10 20
30 40
julia> z[2]
2×2×2 Array{Int64,3}:
[:, :, 1] =
1 2
3 4
[:, :, 2] =
10 20
30 40
现在它将作为以下字符串保存到文件中:
julia> repr(z)
"Array{Int64,3}[[1 2; 3 4]\n\n[10 20; 30 40], [1 2; 3 4]\n\n[10 20; 30 40]]"
并且解析这个字符串显然会失败。您需要做的是编辑您的文件,以在大数组的每个条目上添加 cat
方法调用,并将维度 3
作为您要对其进行分类的维度。
这意味着从保存文件的原始内容:
Array{Int64,3}[[1 2; 3 4]
[10 20; 30 40], [1 2; 3 4]
[10 20; 30 40]]
你必须让这个文件包含:
Array{Int64,3}[cat(3, [1 2; 3 4], [10 20; 30 40]),
cat(3, [1 2; 3 4], [10 20; 30 40])]
这些更改可以手动完成,也可以编写程序来执行转换(您必须将 ,
替换为 ), cat(3,
;\n\n
替换为 ,
; 确保添加第一个 cat
和最后一个 )
,因为它们不会被前两个规则捕获)。
现在,如果您将它作为字符串读取,您可以评估解析它的结果:
julia> s = """Array{Int64,3}[cat(3, [1 2; 3 4], [10 20; 30 40]),
cat(3, [1 2; 3 4], [10 20; 30 40])]"""
"Array{Int64,3}[cat(3, [1 2; 3 4], [10 20; 30 40]),\ncat(3, [1 2; 3 4], [10 20; 30 40])]"
julia> eval(parse(s))[2]
2×2×2 Array{Int64,3}:
[:, :, 1] =
1 2
3 4
[:, :, 2] =
10 20
30 40
但是请注意,不推荐所有这些 - 最好使用 Colin 推荐的包来执行此操作。
不是直接回答你的具体问题,而是对未来发展的一般性建议。要将数据保存到磁盘并稍后重新加载,请优先使用 JLD2.jl
.
等格式
您使用
保存
@save "filename.jld2" ARRAY
并加载
@load "filename.jld2" ARRAY
无需弄清楚您过去选择的格式是什么。避免复杂数据结构的麻烦。
我是 Julia 新人,所以请不要评判我(哈哈)
这是我的情况:我需要保存几个 2x2x2 矩阵,其元素是 4 个元素的向量,但现在当我尝试从文件中检索它们时,我不能!!!
这是我做的:
为了创建这些矩阵,我创建了这个函数
function InitialConf(L_=2,S_=2,T_=2,Dim_=4)
Conf_=Array{Array{Float64,1}}(L_,S_,T_)
for i_ = 1:L_, j_=1:S_,k_=1:T_
Conf_[i_,j_,k_]=RanUniVec(Dim_)
end
return Conf_
end
其中 RanUniVec(Dim_) 是创建这些具有特殊特征的 4 维向量的函数,这些特征对于本次讨论并不重要:
function RanUniVec(Dim_)
vector_=Array{Float64}(Dim_)
while true
for i_ in 1:Dim_
vector_[i_]=UniformRand(-1,1)
end
if norm(vector_)<1 && norm(vector_)>0.5
break
end
end
vector_=normalize(vector_) # 2-norm
return vector_
end
function UniformRand(a_,b_)
rand_=(b_-a_)*rand()+a_
return rand_
end
我需要其中两个矩阵(例如)所以我做了下一个:
States=[]
Conf1=InitialConf()
Conf2=InitialConf()
push!(States,Conf1)
push!(States,Conf2)
f=open("Info.txt","w") do f
write(f,"$States")
end
这使得我的信息所在的 Info.txt 文件,但是当我再次尝试从中获取 States 数组时这个文件,Julia 告诉我它不能
f=readlines("Info.txt")
States=parse(f)
ERROR: MethodError: no method matching parse(::Array{String,1})
Closest candidates are:
parse(::Type{IPv4}, ::AbstractString) at socket.jl:167
parse(::Type{IPv6}, ::AbstractString) at socket.jl:218
parse(::Type{DateTime}, ::AbstractString, ::DateFormat{Symbol("yyyy-mm-dd\THH:MM:SS.s"),Tuple{Base.Dates.DatePart{'y'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'m'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'d'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'H'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'M'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'S'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'s'}}}) at dates/parse.jl:202
...
你知道我怎样才能再次获得我的 State 数组吗?
一般来说,您应该使用长 运行 评论中 Colin 的推荐。如果您确实已经生成了这些文本文件,那么您可以执行以下操作。我将使用一个较小的示例。
假设您的原始数组由两个 2x2x2 数组组成。这是我将使用的示例:
julia> z
2-element Array{Array{Int64,3},1}:
[1 2; 3 4]
[10 20; 30 40]
[1 2; 3 4]
[10 20; 30 40]
julia> z[1]
2×2×2 Array{Int64,3}:
[:, :, 1] =
1 2
3 4
[:, :, 2] =
10 20
30 40
julia> z[2]
2×2×2 Array{Int64,3}:
[:, :, 1] =
1 2
3 4
[:, :, 2] =
10 20
30 40
现在它将作为以下字符串保存到文件中:
julia> repr(z)
"Array{Int64,3}[[1 2; 3 4]\n\n[10 20; 30 40], [1 2; 3 4]\n\n[10 20; 30 40]]"
并且解析这个字符串显然会失败。您需要做的是编辑您的文件,以在大数组的每个条目上添加 cat
方法调用,并将维度 3
作为您要对其进行分类的维度。
这意味着从保存文件的原始内容:
Array{Int64,3}[[1 2; 3 4]
[10 20; 30 40], [1 2; 3 4]
[10 20; 30 40]]
你必须让这个文件包含:
Array{Int64,3}[cat(3, [1 2; 3 4], [10 20; 30 40]),
cat(3, [1 2; 3 4], [10 20; 30 40])]
这些更改可以手动完成,也可以编写程序来执行转换(您必须将 ,
替换为 ), cat(3,
;\n\n
替换为 ,
; 确保添加第一个 cat
和最后一个 )
,因为它们不会被前两个规则捕获)。
现在,如果您将它作为字符串读取,您可以评估解析它的结果:
julia> s = """Array{Int64,3}[cat(3, [1 2; 3 4], [10 20; 30 40]),
cat(3, [1 2; 3 4], [10 20; 30 40])]"""
"Array{Int64,3}[cat(3, [1 2; 3 4], [10 20; 30 40]),\ncat(3, [1 2; 3 4], [10 20; 30 40])]"
julia> eval(parse(s))[2]
2×2×2 Array{Int64,3}:
[:, :, 1] =
1 2
3 4
[:, :, 2] =
10 20
30 40
但是请注意,不推荐所有这些 - 最好使用 Colin 推荐的包来执行此操作。
不是直接回答你的具体问题,而是对未来发展的一般性建议。要将数据保存到磁盘并稍后重新加载,请优先使用 JLD2.jl
.
您使用
保存@save "filename.jld2" ARRAY
并加载
@load "filename.jld2" ARRAY
无需弄清楚您过去选择的格式是什么。避免复杂数据结构的麻烦。