如何在Ruby中的时间序列中规范化和插入缺失值?

Joh*_*lla 3 ruby arrays time-series

假设我有一个带有时间/值对数组的Ruby数组,例如:

[
  # about 9:00 AM on consecutive days
  [<DateTime: 2014-05-15T09:00:00Z>, 56],
  [<DateTime: 2014-05-16T09:06:00Z>, 57],
    # ... missing data for May 17th, 2014
    # ... missing data for May 18th, 2014
  [<DateTime: 2014-05-19T08:57:00Z>, 61],
  # ...
]
Run Code Online (Sandbox Code Playgroud)

请注意,(1)每天不会在同一时间收集值,并且(2)缺少某些值.

我想通过以下方式规范化数据:

  1. 对它进行重新采样,使它们在时间和时间上相等
  2. 插入任何缺失值.

以编程方式执行此操作的正确方法是什么?

更新1

你想如何插值?在你的例子中[58,59],[58,60]和[59,60]同样合情合理.

预期值将取决于使用的插值策略(例如,线性,二次等),因此我无法提供准确的答案.

我愿意接受任何插值策略,以最小的误差预测原始的实际数据点(例如<0.1%).我愿意接受任何导致时间序列观测间隔相等的归一化策略.

Ste*_*fan 5

您可以使用样条插值.以下是使用Spliner gem的示例:

require 'date'
require 'spliner'

arr = [
  [DateTime.new(2014,5,15,9), 56],
  [DateTime.new(2014,5,16,9,6), 57],
  [DateTime.new(2014,5,19,8,57), 61]
]

spline = Spliner::Spliner.new(arr.to_h, extrapolate: '10%')

(DateTime.new(2014,5,15,9)..DateTime.new(2014,5,19,9)).each do |date|
  puts "#{date}: #{spline[date]}"
end
Run Code Online (Sandbox Code Playgroud)

输出:

2014-05-15T09:00:00+00:00: 56.0                 # exact value
2014-05-16T09:00:00+00:00: 56.995496729398646   # interpolated value
2014-05-17T09:00:00+00:00: 58.18937752978536    # interpolated value
2014-05-18T09:00:00+00:00: 59.55365781173006    # interpolated value
2014-05-19T09:00:00+00:00: 61.0030489943531     # extrapolated value
Run Code Online (Sandbox Code Playgroud)