首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用ruby压缩时间序列数据流

使用ruby压缩时间序列数据流
EN

Stack Overflow用户
提问于 2015-10-07 21:45:06
回答 3查看 126关注 0票数 2

我有一个想要从传感器读取的流。这条小溪永远不会结束。大多数时候,这些值会随着时间的推移而重复。因此,我想确定值的运行,只保留每次运行的第一次和最后一次,并保留它们的时间戳。

['8:00',4,'8:01',4,'8:02',4,'8:03',7,'8:04',7,'8:05',8,'8:06',9,'8:07',13,'8:08',13,'8:09',13].lazy

我想将此数据压缩为:['8:00',4,'8:02',4,'8:03',7,'8:04',7,'8:05',8,'8:06',9,'8:07',13,'8:09',13]

然而,这个问题似乎具有内在的功能性。

EN

回答 3

Stack Overflow用户

发布于 2015-10-07 23:16:32

代码语言:javascript
运行
复制
data.reduce([data.first]) do |result, item|
  result.last.last == item.last ? result : result + [item]
end

这并不能精确地产生您想要的输出-它跳过了运行的最后一项。但好消息是您不需要最后一项,因为您知道它的值与您的第一项相同,并且您知道它的时间戳比下一项小一。(如果您的时间戳不是连续的,那么这是不好的)。如果最后一个条目也不在Time.now上,最简单的做法就是在最后手动添加它。

它的用途:

  • 使用第一个值初始化结果。

我已经编写了它,以便每次迭代都会生成一个带有result + [item]的新result数组,这是使用reduce的函数风格和首选方式,但这会产生许多不必要的中间数组。您可以只通过实际追加(<<)来创建一个新数组。

票数 0
EN

Stack Overflow用户

发布于 2015-10-08 20:14:56

这不是一个优雅的解决方案,但它是有效的。

代码语言:javascript
运行
复制
data = ['8:00', 4],['8:01', 4],['8:02', 4],['8:03', 7],['8:04', 7],['8:05', 8],['8:06', 9],['8:07', 13],['8:08', 13],['8:09', 13]

def clean_array(data)
    item_to_delete = []

    (0..(data.count-3)).each do |i|
        if data[i][1].eql?(data[i+2][1])
            item_to_delete << data[i+1]
        end
    end

    data - item_to_delete
end

new_data = clean_array(data)

正如预期的那样,输出是

代码语言:javascript
运行
复制
=> [["8:00", 4], ["8:02", 4], ["8:03", 7], ["8:04", 7], ["8:05", 8], ["8:06", 9], ["8:07", 13], ["8:09", 13]]

编辑

另一种方法

代码语言:javascript
运行
复制
data = ['8:00', 4],['8:01', 4],['8:02', 4],['8:03', 7],['8:04', 7],['8:05', 8],['8:06', 9],['8:07', 13],['8:08', 13],['8:09', 13]    
new_data = []

data.each { |item| (new_data[-2] and item[1].eql?(new_data[-2][1])) ? new_data[-1] = item : new_data << item }

new_data

# => => [["8:00", 4], ["8:02", 4], ["8:03", 7], ["8:04", 7], ["8:05", 8], ["8:06", 9], ["8:07", 13], ["8:09", 13]]
票数 0
EN

Stack Overflow用户

发布于 2015-10-09 05:43:48

我正在发布我自己问题的解决方案。我从Kristján的解决方案开始,它使用了reduce。请注意,我的解决方案无法生成最终的采样时间,但我选择接受此行为,因为我的示例只是用于模拟流。所以8:09样本并不是最终的值。下一个传入的样本将确定是否存储该8:09值。因此,我的原始帖子的细节可以更好地解释。

代码语言:javascript
运行
复制
samples = [['8:00', 4],['8:01', 4],['8:02', 4],['8:03', 7],['8:04', 7],['8:05', 8],['8:06', 9],['8:07', 13],['8:08', 13],['8:09', 13]].lazy

prev = []
compressed = samples.reduce([samples.first]) do |keepers, sample|
  keepers << prev << sample if keepers.last.last != sample.last
  prev = sample
  keepers
end
puts compressed.inspect

# => [["8:00", 4], ["8:02", 4], ["8:03", 7], ["8:04", 7], ["8:05", 8], ["8:05", 8], ["8:06", 9], ["8:06", 9], ["8:07", 13]]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32993904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档