利用多个时间序列数据作图时,一般要将不同时间序列按时间对齐,然后分段求取特征值,代表该时间段的值.

我最近将Julia程序中所有与时间有关的变量全部用DateTime代替.完成之后发现转化时序观测到二维图时,数据总是有问题. 通过尝试不同数据和参数,发现主要是时间到二维图的数组下标之间转化出问题.但是该段程序是完全没有动过的.唯一变化的是输入时间由表示Julianday的Float64改为代表时刻的Datetime.

在调试过程中想到是不是round的行为与我所认为的有区别?

如下的代码基本上就是发现和验证问题的过程.包括创建起止DateTime,构建时间点,然后作差,得到时间间隔,最后与所需间隔相除得到可以近似看做数组中偏移量的浮点数,最后roundInt64.

julia> using Dates
julia> a = DateTime(1)
0001-01-01T00:00:00

julia> b = a+Minute(5)
0001-01-01T00:05:00

julia> a+=Second(15)
0001-01-01T00:00:15

julia> intveral = Millisecond(30_000)
30000 milliseconds


julia> dts = collect(a:intveral:b)
10-element Array{DateTime,1}:
 0001-01-01T00:00:15
 0001-01-01T00:00:45
 0001-01-01T00:01:15
 0001-01-01T00:01:45
 0001-01-01T00:02:15
 0001-01-01T00:02:45
 0001-01-01T00:03:15
 0001-01-01T00:03:45
 0001-01-01T00:04:15
 0001-01-01T00:04:45


julia> (dts.-DateTime(1))/intveral
10-element Array{Float64,1}:
 0.5
 1.5
 2.5
 3.5
 4.5
 5.5
 6.5
 7.5
 8.5
 9.5


julia> round.(Int64,(dts.-DateTime(1))/intveral)
10-element Array{Int64,1}:
  0
  2
  2
  4
  4
  6
  6
  8
  8
 10


julia> round(Int64,2.5)
2

julia> round(Int64,1.5)
2

可以看到round的含义有一点差异.

这个时候开源语言的优势就显示出来了,直接到Github上找相关的代码,发现如下解释:

"""
    RoundNearest
The default rounding mode. Rounds to the nearest integer, with ties (fractional values of
0.5) being rounded to the nearest even integer.
"""

github.com/julia

在Google的帮助下,又找到几个相关的网页: 1, 2, 3.

这种行为是IEEE标准规定的默认行为,同时在讨论概率的情形下,这样的操作还更能接近真值.

如果round结果不是用作index,使得结果出现明显偏差,这个还真是隐藏在程序中bug. 不过了解之后,就可以添加相应语句使得程序行为符合自己的想法.

最后就是开源的优势之一就是在遇到问题时可以直接找源码.

发表评论

电子邮件地址不会被公开。 必填项已用*标注