如何在Julia中写入和读取包含datetime列的数据帧
第二次更新:用户@Matt B确认为一个bug。有关更多详细信息,请参见下面的答案 更新:@waTeim已经证明,可以写入和读取包含日期类型列的数据帧(在我的设置中确认)。这很重要,因为这意味着Julia可以写入和读取数据帧列中的某些复合类型。但是,datetime类型(与date类型不同)仍然会抛出一个错误,因此在这一点上问题仍然没有答案 在Julia中,使用HDF5和JLD包,可以在.JLD文件中保存和加载数据帧,例如:如何在Julia中写入和读取包含datetime列的数据帧,datetime,dataframe,hdf5,julia,Datetime,Dataframe,Hdf5,Julia,第二次更新:用户@Matt B确认为一个bug。有关更多详细信息,请参见下面的答案 更新:@waTeim已经证明,可以写入和读取包含日期类型列的数据帧(在我的设置中确认)。这很重要,因为这意味着Julia可以写入和读取数据帧列中的某些复合类型。但是,datetime类型(与date类型不同)仍然会抛出一个错误,因此在这一点上问题仍然没有答案 在Julia中,使用HDF5和JLD包,可以在.JLD文件中保存和加载数据帧,例如: #Preamble using HDF, JLD, DataFrame
#Preamble
using HDF, JLD, DataFrames
filePath = "/home/colin/Test.jld";
#Save the data-frame
fid1 = jldopen(FP, "w");
write(fid1, "MyDataFrame", MyDataFrame);
close(fid1);
#Come back later and load the data-frame
fid1 = jldopen(FP, "r");
X = read(fid1, "MyDataFrame");
close(fid1);
只要数据帧的列都是基本Julia类型的向量,如Float64
或Int64
,这种方法就可以很好地工作。但是,在实践中,我们通常希望数据帧的第一列是日期时间
,它不是基类型(尽管在将来的版本中可能会成为基类型)。在这种情况下,上面的代码在read
操作中失败,并显示一条很长的错误消息(如果有人在评论中询问,我会将其添加到底部)。根据JLD软件包的文档,我在保存时尝试了以下操作:
#Save the data-frame
fid1 = jldopen(FP, "w");
addrequire(fid1, "/home/colin/.julia/v0.2/DataFrames/src/dataframe.jl")
addrequire(fid1, "/home/colin/.julia/v0.2/Datetime/src/Datetime.jl")
write(fid1, "MyDataFrame", MyDataFrame);
close(fid1);
但这没有帮助
我是在做一些愚蠢的事情,还是这个功能根本不可用
注意:包含HDF5标记是因为JLD软件包使用它。当缺少对特定数据类型的HDF5支持时,可能会出现此错误。在本例中,并不是特别使用Datetime的DataFrames,而是缺少对Datetime类型本身的支持。显然,当库由于任何原因(以及其他示例)无法加载类型时。每种类型的确切原因和修复都不同,但报告错误会导致提示修复(见下文) 错误 历史的 版本0.2.25 我建议您迁移到Julia版本0.3,因为它现在处于发行候选状态,并更新您的包存储库。我的设置不同;我使用不同版本的HDF5、JLD、数据帧和日期时间。但话说回来,我所做的两个重要更改只是在调用addrequire时指示模块名而不是文件名,并且还使用@read和@write宏,而不是相应的函数,因为后者似乎有缺陷
Version 0.3.0-rc1+4263 (2014-07-19 02:59 UTC)
Pkg.status()
- DataFrames 0.5.7
- HDF5 0.2.25
- Datetime 0.1.6
创建数据文件
using HDF5,JLD,DataFrames,Datetime
testFile = jldopen("test.jld","w")
addrequire(testFile,"DataFrames")
addrequire(testFile,"Datetime")
df = DataFrame()
df[:column1] = today()
@write testFile df
close(testFile)
重新启动茱莉亚和阅读
julia> using HDF5,JLD,DataFrames,Datetime
julia> testFile = jldopen("test.jld","r")
Julia data file version 0.0.2: test.jld
julia> @read testFile df
1x1 DataFrame
|-------|------------|
| Row # | column1 |
| 1 | 2014-07-19 |
julia> df[:column1]
1-element DataArray{Date{ISOCalendar},1}:
2014-07-19
版本0.2.25+(预发布)
事实上,我可以证实,试图存储Datetime失败了,使用回购协议中的最新版本解决了这个问题
HDF5 0.2.25+ master
如果仅通过将今天的更改为现在的()
接下来
julia> using HDF5,JLD,DataFrames,Datetime
julia> testFile = jldopen("test.jld","r")
Julia data file version 0.0.2: test.jld
julia> @read testFile df
1x1 DataFrame
|-------|-------------------------|
| Row # | column1 |
| 1 | 2014-07-26T03:38:45 UTC |
但是,Datetime中出现的相同的一般性错误消息也会出现在复杂类型中
版本0.2.26
此版本还支持复杂的。最初看来,这个问题通常缺乏对complex类型的支持,但更可能是从1+im初始化complex的特殊问题;而不是1.0+im
正如我在上面的评论中所指出的,这就是现在已经发生的行为。在0.2.26版本被标记之前,您可以使用
Pkg.checkout(“HDF5”)
来修复此错误
但为了让这更像一个答案,我将更详细地描述这个问题,并给出一个潜在的解决方法。
Date
和DateTime
类型都是带有。在HDF5.jl包中保存和加载bitstypes是一项相对较新的功能;仅支持(标记为版本0.2.24和0.2.25)
这些版本有一个bug,其中BitStype的类型名不能与其模块名(作为完全限定的类型名)一起保存。您可以在导入
和使用
之间的区别中非常清楚地看到这一点:
julia> using HDF5, JLD # version 0.2.25
julia> import Datetime
julia> save("today.jld","t",Datetime.today()) # today() returns a `Datetime.Date`
julia> load("today.jld") # But it was saved as just a `Date`, not a `Datetime.Date`
# so HDF5 cannot find the definition
HDF5-DIAG: Error detected in HDF5 (1.8.11) thread 0:
#000: H5Dio.c line 182 in H5Dread(): can't read data … # backtrace truncated
julia> using Datetime # Bring `Date` into the `Main` namespace
julia> load("today.jld") # now it works!
Dict{Union(UTF8String,ASCIIString),Any} with 1 entry:
"t" => 2014-07-25
因此,当您要保存日期时间
对象时,它由日历
和时区偏移量参数化。但是,Offset
类型并不是从Datetime包中导出的……它们有很多!但是,大多数日期时间只使用Zone0
:UTC。因此,如果您使用HDF5.jl版本0.2.24-25保存了日期时间数据,则可以通过手动将这些类型“导出”到主命名空间来恢复数据
julia> save("now.jld","n",now())
julia> load("now.jld")
HDF5-DIAG: Error detected in HDF5 (1.8.11) thread 0:
#000: H5Dio.c line 182 in H5Dread(): can't read data … # truncated
julia> const Zone0 = Datetime.Zone0;
julia> load("now.jld")
Dict{Union(UTF8String,ASCIIString),Any} with 1 entry:
"n" => 2014-07-25T13:45:45 UTC
序列化()和反序列化()是否有可能满足您的需要?你不会得到一个.jld,但你应该能够做i/o。@Mageek
serialize()
和deserialize()
可能可以工作,但从长远来看,解决方案是不可行的,因为不同版本的Julia或甚至运行在不同系统上的Julia实例可能无法读回写入的相同数据。不过谢谢你的想法,很抱歉我花了这么长时间才回复。这是一个bug。报告时间:现在应该修复!如果您仍然有问题,请告诉我(在标记新版本的HDF5之前,您可以使用Pkg.checkout(“HDF5”)
获取此修补程序)。@MattB。谢谢Matt,我已经确认了我的设置。现在都在工作。如果你想写一个非常简短的答案,表明这是一个bug,并且已经修复,我会投票并给出答案。谢谢你的回复。我明天会试试这个。很有趣。您的示例很有效,但我认为这是因为您使用的是typeDate
,而不是Datetime
,即typeof(today())
返回Date{ISOCalendar}
。如果将示例中的df[:column1]=today()替换为df[:column1]=datetime(2001,1,1,1,1,1)
那么我相信你会看到我看到的错误。我应该向其他读者澄清:这很有趣,因为类型Date
也是Datetime
包的一部分。这意味着问题具体在于
c = 1 + im;
@write testFile c
- HDF5 0.2.26
julia> using HDF5, JLD
julia> testFile = jldopen("test.jld","r")
Julia data file version 0.0.2: test.jld
julia> @read testFile c
1 + 1im
julia> using HDF5, JLD # version 0.2.25
julia> import Datetime
julia> save("today.jld","t",Datetime.today()) # today() returns a `Datetime.Date`
julia> load("today.jld") # But it was saved as just a `Date`, not a `Datetime.Date`
# so HDF5 cannot find the definition
HDF5-DIAG: Error detected in HDF5 (1.8.11) thread 0:
#000: H5Dio.c line 182 in H5Dread(): can't read data … # backtrace truncated
julia> using Datetime # Bring `Date` into the `Main` namespace
julia> load("today.jld") # now it works!
Dict{Union(UTF8String,ASCIIString),Any} with 1 entry:
"t" => 2014-07-25
julia> save("now.jld","n",now())
julia> load("now.jld")
HDF5-DIAG: Error detected in HDF5 (1.8.11) thread 0:
#000: H5Dio.c line 182 in H5Dread(): can't read data … # truncated
julia> const Zone0 = Datetime.Zone0;
julia> load("now.jld")
Dict{Union(UTF8String,ASCIIString),Any} with 1 entry:
"n" => 2014-07-25T13:45:45 UTC