通过时间戳将项目组合到间隔箱中

Posted

技术标签:

【中文标题】通过时间戳将项目组合到间隔箱中【英文标题】:Combining items into interval bins by timestamps 【发布时间】:2015-06-16 15:53:42 【问题描述】:

这基本上是我需要做的,但我没有使用表格,所以我需要在 Ruby/Rails 甚至 javascript 中完成。数据是从一个有点慢的外部调用返回的,所以我试图尽快格式化数据。可能有多达数千个元素。

我得到这个输入:

"data": [
            "time": "2015-04-01 05:10","count": 1,
            "time": "2015-04-01 06:00","count": 3,
            "time": "2015-04-01 06:50","count": 2,
            "time": "2015-04-01 07:40","count": 8,
            "time": "2015-04-01 07:48","count": 5
        ]

并且想要返回这样的东西(带有 1 小时的存储桶):

"buckets": [
              "time": "2015-04-01 05:00", "count": 1,
              "time": "2015-04-01 06:00", "count": 5,
              "time": "2015-04-01 07:00", "count": 13
            ]

我唯一能想到的就是使用一堆 if 并迭代添加到计数 if hour === last.hour else 如果它不同则创建一个新元素。不过感觉肯定有更优雅的解决方案。

我似乎无法在 Ruby/Javascript 中找到一个好的解决方案。这是相同的想法,但这些都不在我的数据库中。 Grouping into interval of 5 minutes within a time range

如果我希望用户能够选择按小时、天、周等查看数据。这是最好的策略吗?

【问题讨论】:

两者都是很好的答案。我接受了答案,这使我不必将日期格式化回输入格式。谢谢你们! 【参考方案1】:

将时间四舍五入到小时,并使用聚合计数建立一个新的哈希值。如果您希望用户选择一个时间段,只需根据存储桶大小选择strftime 格式。您可以对 Time 对象进行数学运算,但无论如何您都要对其进行格式化,所以不妨在那里进行。由于您在 Rails 中,您还可以使用 Time#beginning_of_* 方法。

如果您的数据在 data.json 中,这里有一个脚本会执行此操作:

require 'json'
require 'time'

data = JSON.parse(File.read('data.json'))['data']

result = Hash.new(0) # Missing entries get initialized to 0

data.each do |entry|
  time = Time.parse(entry['time'])
  hour = time.strftime('%Y-%m-%d %H:00') # Effectively round to the hour
  result[hour] += entry['count']
end

result_list = result.map do |time, count|
  time: time, count: count
end
puts JSON.pretty_generate(buckets: result_list)

输出:

$ ruby group.rb

  "buckets": [
     "time": "2015-04-01 05:00", "count": 1 ,
     "time": "2015-04-01 06:00", "count": 5 ,
     "time": "2015-04-01 07:00", "count": 13 
  ]

【讨论】:

【参考方案2】:

在使用 beginning_of_hour 的 Rails 中,您可以像这样将时间组合在一起:

a = [
     "time"=>"2015-04-01 05:10","count"=>1,
     "time"=>"2015-04-01 06:00","count"=>3,
     "time"=>"2015-04-01 06:50","count"=>2,
     "time"=>"2015-04-01 07:40","count"=>8,        
     "time"=>"2015-04-01 07:48","count"=>5                     
    ] 

hash = Hash.new(0)
a.each |k|
  hash[k["time"].to_time.beginning_of_hour] += k["count"]


hash.map|k,v| "time" => k, "count" => v
# => ["time"=>2015-04-01 05:00:00 UTC, "count"=>1, "time"=>2015-04-01 06:00:00 UTC, "count"=>5, "time"=>2015-04-01 07:00:00 UTC, "count"=>13]

【讨论】:

以上是关于通过时间戳将项目组合到间隔箱中的主要内容,如果未能解决你的问题,请参考以下文章

根据 postgresQL 中的时间戳将值从一个表映射到另一个表

使用 python 或 bash 按时间戳将音频文件复制到新文件夹

从小的、大小相同的连续箱中重叠和分类计数到不规则、不均匀的箱中

如何为节点红色的模块添加一定的时间间隔?

通过键入选择组合框中的项目

如何通过值组合选择项目