一、包的介绍
JLD2 saves and loads Julia data structures in a format comprising a subset of HDF5, without any dependency on the HDF5 C library. It typically outperforms the JLD package (sometimes by multiple orders of magnitude) and often outperforms Julia's built-in serializer. While other HDF5 implementations supporting HDF5 File Format Specification Version 3.0 (i.e. libhdf5 1.10 or later) should be able to read the files that JLD2 produces, JLD2 is likely to be incapable of reading files created or modified by other HDF5 implementations. JLD2 does not aim to be backwards or forwards compatible with the JLD package.
JLD2来源于HDF5,但是它没有用hdf5的C库,完全自己动手纯julia实现,JLD2用来保存和加载Julia数据类型。以前有一个包叫JLD,(我没查过资料,不做评论),官网说JLD2性能远超JLD,甚至通常胜过Julia的内置序列化器
它的好处就是把julia的数据类型直接存在硬盘上,比如我们用的datafarame,直接系列化到硬盘上,而不是存成xecel或者csv然后在读取,以csv为例,虽然它的文件比较小,但是有可能会丢失一些数据类型信息。
另外,我们可以用键、值来保存信息,好处是方便数据提取。打个比方,回测时用到【指数】、【基金】、【股票】的k线,我们可以用组来标记【指数】、【基金】、【股票】,然后通过【股票代码】(key)直接提取某一只股票的k线(value)。
同理,计算好的回测指标,比如回测的时候,要快速提取【某只股票】在【某天】的【macd金叉】和【kd指标】数据,我们便可以提前把计算好的数据存成jld2的格式,用的时候,直接调入内存,进行快速提取,大大节约回测时间。特别是涉及到参数组合优化的时候,往往需要进行大量的计算(可能需要连续开机计算计算好几天),这时候,就能够展现key-value数据格式的优点。
给定一组参数,要选取最优组合的时候,往往涉及大量的计算,并且需要保存大量的中间计算结果。假如你要保存1600万个中间计算结果(组合状态 对应 表格数据),如果你把每个文件的直接写到硬盘上,估计很慢,而且再次复用的时候,读取速度又是一大麻烦。此时用字典来组织内存数据,当达到一定的大小后,挂上关键字信息分批写入jld2文件中
二、地址:
https://github.com/JuliaIO/JLD2.jl
三、安装
Pkg.add("JLD2")
四、save和load的几种使用方法
几种保存和读取jld2文件的方式
4.1 @save 和 @load
using JLD2
hello = "world"
foo = :bar
name = "张翠山"
@save "example.jld2" hello foo
@load "example.jld2"
@load "example.jld2" foo
@load "example.jld2" hello foo
@save "example.jld2" name
@load "example.jld2"
代码运行结果
以上我们使用save和load宏进行一个变量的保存和加载,如果我们有一个dataframe,能不能保存到jld2文件里呢?
mydf = DataFrame(姓名 = ["a","b","c","d","e"],年龄 = [1,2,3,4,5])
@save "example.jld2" mydf
@load "example.jld2"
你会发现,你并没有保存dataframe,那要如何操作呢?如何对键、值数据(字典)进行save和load?
4.2 FileIO中的save 和load
The save function accepts an AbstractDict yielding the key/value pairs, where the key is a string representing the name of the dataset and the value represents its contents。
FileIO中的save可以用来保存字典,注意,key只能是字符串。另外,在使用FileIO中的save和load的时候,不需要using JLD2,因为FileIO包会自动识别它操作的是啥。
using FileIO
mydict = Dict("df" => DataFrame(姓名 = ["a","b","c","d","e"],年龄 = [1,2,3,4,5]))
save("example.jld2", mydict)
load("example.jld2")
代码运行结果
注意: save也可以用来保存一般的变量,但是,它会进行装箱操作,看下面的例子:
save("example.jld2", "hello", "world", "foo", :bar) #它会自动装箱成Dict,按照key=>value逐对匹配
load("example.jld2")
"""
输出结果为:
Dict{String,Any} with 2 entries:
"hello" => "world"
"foo" => :bar
"""
save("example.jld2", "name", "张翠山") #这里不是增加一个键值对,而是用新装箱的dict把源文件覆盖重写
load("example.jld2")
"""
输出结果为:
Dict{String,Any} with 1 entry:
"name" => "张翠山"
"""
你以为保存了2个变量,实际上却是保存了一个键值对,哈哈哈
问题:我已经在jld2文件里保存了一个字典了,我怎样把一个新的【键值对】插入到jld2的字典中
4.3 FileIO中save和load的另一种用法
4.3.1 像操作普通文件一样操作jld2数据,多种open方式
f = jldopen("example.jld2", "r") # open read-only (default)
f = jldopen("example.jld2", "r+") # open read/write, failing if no file exists
f = jldopen("example.jld2", "w") # open read/write, overwriting existing file
f = jldopen("example.jld2", "a+") # open read/write, preserving contents of existing file or creating a new file
注意,f对象在使用完毕后,一定要close(f)
#读取hello键对应的值
f = jldopen("example.jld2", "r")
f["hello"] |> println
close(f) #记得关闭
#重置hello键对应的值
f = jldopen("example.jld2", "w")
f["hello"] = "你好"
f["hello"] |> println
close(f) #记得关闭
open的变种用法
4.3.2 open的变种用法
jldopen和do
jldopen("example.jld2", "a+") do file
file["bigdata111"] = randn(5)
file["bigdata112"] = randn(5)
file["bigdata113"] = randn(5)
end
4.4 Group的使用
Group是什么东西,你可以理解成字典中的一个key,每个key下面,又是一个字典。你可以理解成一个文件夹,通过这个文件夹的路径,我们可以访问这个文件夹下的文件。
using FileIO
save("example.jld2", Dict("hello" => "world", "foo" => :bar))
jldopen("example.jld2", "a+") do file
mygroup = JLD2.Group(file, "mygroup")
mygroup["mystuff"] = 42
mygroup["mystuff1"] = 43
end
load("example.jld2")
代码运行结果
红色部分为新建mygroup组下的节点数据
【注意事项】 用【@save】和【save】保存后的jld2文件,存在一定差别,如下图红色部所示:
其它问题:
1、加载JLD2文件的时候,出现关于”DataFrames“的警告,什么原因,之前都没遇到的?
┌ Warning: type DataFrames.DataFrame does not exist in workspace; reconstructing
└ @ JLD2 C:\Users\dengz.juliapro\JuliaPro_v1.4.2-1\packages\JLD2\4AJn8\src\data.jl:1190
┌ Warning: type DataFrames.Index does not exist in workspace; reconstructing
└ @ JLD2 C:\Users\dengz.juliapro\JuliaPro_v1.4.2-1\packages\JLD2\4AJn8\src\data.jl:1190
┌ Warning: type DataFrames.DataFrame does not exist in workspace; reconstructing
└ @ JLD2 C:\Users\dengz.juliapro\JuliaPro_v1.4.2-1\packages\JLD2\4AJn8\src\data.jl:1190
┌ Warning: type DataFrames.Index does not exist in workspace; reconstructing
└ @ JLD2 C:\Users\dengz.juliapro\JuliaPro_v1.4.2-1\packages\JLD2\4AJn8\src\data.jl:1190
、
原因:jld2数据文件里面有DataFrames的数据,但是程序开始没有using DataFrames的包,导致无法识别数据类型。using后,不在出现报警。
文中的谬误,还望不吝指正。