这里主要介绍Julia 时间序列分析库 TimeSeries 的用法。
其实TimeSeries中的很多用法都可以在DataFrame.jl 中找到。而且TimeArray 和DataFrame 都是可以互转的。
(1)基础数据类型使用,取数
using Dates
using TimeSeries
using MarketData
################(1)数据索引#######
#tuple 类型的数据,封装到TimeArray中,注意:一定要指定时间戳 timestamp = :datetime
dates = Date(2018, 1, 1):Day(1):Date(2018, 12, 31)
data = (datetime = dates,col1 =rand(length(dates)),col2 = rand(length(dates)))
ta = TimeArray(data; timestamp = :datetime, meta = "Example")
#列名
colnames(ta)
#取某一行
ta[1]
#无论取那一列,都会带上timestamp
ta[1,:col1]
# 1×1 TimeArray{Float64,2,DateTime,Array{Float64,2}} 2018-11-21T12:00:00 to 2018-11-21T12:00:00
# │ │ col1 │
# ├─────────────────────┼───────┤
# │ 2018-11-21T12:00:00 │ 10.2 │
(2)数据分片
################(2)数据分片#######
# when函数-指定时间段的数据,支持的时段类型如下:
# Dates method Example
# day Jan 3, 2000 = 3
# dayname Jan 3, 2000 = "Monday"
# week Jan 3, 2000 = 1
# month Jan 3, 2000 = 1
# monthname Jan 3, 2000 = "January"
# year Jan 3, 2000 = 2000
# dayofweek Monday = 1
# dayofweekofmonth Fourth Monday in Jan = 4
# dayofyear Dec 31, 2000 = 366
# quarterofyear Dec 31, 2000 = 4
# dayofquarter Dec 31, 2000 = 93
when(ta, dayofweek, 1)
when(ta, dayname, "Monday")
when(ta, year, 2018)
when(ta, dayofweekofmonth, 1)
#设置timestamp索引的开始时间
from(ta, Date(2018, 12, 27))
#设置timestamp索引的截至时间
to(ta, Date(2018, 2, 27))
#找出符合条件的timestamp索引
index = findwhen(ta[:col1] .> ta[:col2])
#根据timestamp索引查询所有的数据
ta[index]
#找出符合条件的row序号,然后根据序号查找数据
index = findall(ta[:col1] .> ta[:col2]);
ta[index]
#从头部取多少条数据
head(ta,1)
#从尾部取多少条数据
tail(ta,1)
(3)列名修改
################(3)列名修改#######
rename(ta, :col1 => :col) |> first
rename!(ta, :col1 => :col) |> first
#关于操作符
#TimeSeries函数使用的 算术、比较、逻辑计算符号前面都要加上 .
index = findall(ta[:col1] .> ta[:col2]);
index = findall(ta[:col1] .== ta[:col2]);
(4)常用分析函数
lag函数将数据的时间戳往前移动一天,但是会丢首天的数据,可以使用padding=true参数,表示使用NaN值填充返回的TimeArray
################(4)常用分析函数#######
#lag函数将数据的时间戳往前移动一天,但是会丢首天的数据,可以使用padding=true参数,表示使用NaN值填充返回的TimeArray
lag(head(ta,2))
# 1×2 TimeArray{Float64,2,Date,Array{Float64,2}} 2018-01-02 to 2018-01-02
# │ │ col1 │ col2 │
# ├────────────┼────────┼────────┤
# │ 2018-01-02 │ 0.2811 │ 0.0875 │
lag(head(ta,2),padding=true)
# 2×2 TimeArray{Float64,2,Date,Array{Float64,2}} 2018-01-01 to 2018-01-02
# │ │ col1 │ col2 │
# ├────────────┼────────┼────────┤
# │ 2018-01-01 │ NaN │ NaN │
# │ 2018-01-02 │ 0.2811 │ 0.0875 │
lead 函数将数据的时间戳往后移动一天,但是会丢失最后一天的数据,可以使用padding=true参数,表示使用NaN值填充返回的TimeArray
#lead 函数将数据的时间戳往后移动一天,但是会丢失最后一天的数据,可以使用padding=true参数,表示使用NaN值填充返回的TimeArray
tail(ta,2)
lead(tail(ta,2))
# 1×2 TimeArray{Float64,2,Date,Array{Float64,2}} 2018-12-30 to 2018-12-30
# │ │ col │ col2 │
# ├────────────┼────────┼────────┤
# │ 2018-12-30 │ 0.2034 │ 0.8178 │
lead(tail(ta,2),padding=true)
# 2×2 TimeArray{Float64,2,Date,Array{Float64,2}} 2018-12-30 to 2018-12-31
# │ │ col │ col2 │
# ├────────────┼────────┼────────┤
# │ 2018-12-30 │ 0.2034 │ 0.8178 │
# │ 2018-12-31 │ NaN │ NaN │
#还可以移动指定的天数
lead(tail(ta,100),99)
# 1×2 TimeArray{Float64,2,Date,Array{Float64,2}} 2018-09-23 to 2018-09-23
# │ │ col │ col2 │
# ├────────────┼────────┼────────┤
# │ 2018-09-23 │ 0.2034 │ 0.8178 │
diff 函数计算时间序列中两个连续时间点之间的有限差分。由此产生的时间序列将比原始时间序列具有更少的点数。如果padding=true,则用NaN值填充这些点。有限差分方法(finite difference method)一种求偏微分(或常微分)方程和方程组定解问题的数值解的方法,简称差分方法。
#diff函数计算时间序列中两个连续时间点之间的有限差分。由此产生的时间序列将比原始时间序列具有更少的点数。
#如果padding=true,则用NaN值填充这些点。
#有限差分方法(finite difference method)一种求偏微分(或常微分)方程和方程组定解问题的数值解的方法,简称差分方法。
diff(ta)
#可以使用参数differences计算更高阶的差分值,它接受一个正整数。默认值为differences=1。
#例如,传递differences=2相当于执行diff(diff(ta))
diff(ta,differences=2)
percentchange 计算时间戳之间的变化是一种非常常见的时间序列操作。我们常用的统计方式有百分比变化率,回报率和变化率。根据时间序列的问题域,我们可以选择合适的统计方式。
# percentchange 计算时间戳之间的变化是一种非常常见的时间序列操作。我们常用的统计方式有百分比变化率,回报率和变化率。根据时间序列的问题域,我们可以选择合适的统计方式。
percentchange(cl)
# 对数回报率在下游计算中很流行,因为加上回报率比乘以回报率更简单,
percentchange(cl, :log)
moving函数通常,在处理时间序列时,您希望获取数据的滑动窗口视图并对其执行计算。最简单的例子就是移动平均线。对于10个周期的移动平均值,取前10个值,然后求和,再除以10得到它们的平均值。然后你把窗户一个一个往前滑动。此操作涉及两个重要参数:要在窗口上使用的函数和要应用该函数的窗口的大小。
cl[1:11]
# 11×1 TimeArray{Float64,1,Date,Array{Float64,1}} 2000-01-03 to 2000-01-18
# │ │ Close │
# ├────────────┼────────┤
# │ 2000-01-03 │ 111.94 │
# │ 2000-01-04 │ 102.5 │
# │ 2000-01-05 │ 104.0 │
# │ 2000-01-06 │ 95.0 │
# │ 2000-01-07 │ 99.5 │
# │ 2000-01-10 │ 97.75 │
# │ 2000-01-11 │ 92.75 │
# │ 2000-01-12 │ 87.19 │
# │ 2000-01-13 │ 96.75 │
# │ 2000-01-14 │ 100.44 │
# │ 2000-01-18 │ 103.94 │
#如前所述,我们会失去了前9个时间点的数据。它们本身并不是缺失的,是根本不存在。
moving(mean, cl[1:11], 10)
# 2×1 TimeArray{Float64,1,Date,Array{Float64,1}} 2000-01-14 to 2000-01-18
# │ │ Close │
# ├────────────┼────────┤
# │ 2000-01-14 │ 98.782 │
# │ 2000-01-18 │ 97.982 │
upto/basecall聚合函数
#时间序列分析中的另一个常见操作是聚合函数。TimeSeries通过upto方法支持聚合功能。假设希望跟踪从开始到当前时间戳的所有值的总和。
#您可以使用upto方法,如下所示:
#upto函数
upto(sum, cl)
upto(mean, cl)
#basecall 因为upto方法的算法还需要进一步优化,所以最好再找一个基方法来代替它。我们可以使用basecall方法来实现显著的性能改进
basecall(cl, cumsum)
basecall(cl, mean)
(5)联合函数
#### (5)联合函数 TimeSeries支持合并两个Timearray,当遇到有意义的值时将时间戳压缩为一个较长的时间间隔。
#merge函数,merge方法执行两个时间数组之间的连接。默认是内联接,这样得到的TimeArray只包含两个TimeArray共享的时间戳和对应于该时间戳的值。
AppleCat = merge(AAPL,CAT);
#左连接
merge(op[1:3], cl[2:4], method = :left)
#右连接
merge(op[1:3], cl[2:4], method = :right)
#外连接
merge(op[1:3], cl[2:4], method = :outer)
其他
。。。。。。待续