使用两个时间戳对数据进行分箱

问题描述

我发帖是因为我没有找到与此主题相关的内容

我的目标本质上是生成一个时间分箱图,绘制一些聚合值。 For Example。通常这会很容易,因为每个值都有一个时间戳,因此可以相对直接地进入 bin。

但是,我的问题在于每个值都有两个时间戳 - 开始和结束。类似于甘特图,这里是一个 example of my plotted data。我基本上想将时间线存在于所述 bin 中的值(平均值)分箱(bin 边界可能是新/旧任务开始/结束的地方)。 Likeso

我正在寻找 Vega-Lite 中是否支持的基本示例或答案。我当前的工作示例不会对本次讨论产生任何好处。

解决方法

我看到您找到了 Vega 解决方案,但我认为您在 Vega-Lite 中寻找的内容类似于以下内容。您将开始字段放在 "x" 中,将结束字段放在 x2 中,将 bin 和类型添加到 x 中,一切都应该有效。

"encoding": {
  "x": {
    "field": "start_time","bin": { "binned": true },"type": "temporal","title": "Time"
  },"x2": {
    "field": "end_time"
  }
}
,

我丢失了旧帐户,但我是发布此信息的人。这是我对我的问题的解决方案。我在这里聚合的值是每个数据点的时间线包含在每个 bin 中的时间总和。

  1. 首先,您要使用连接聚合来获取数据扩展到的最大和最小时间。您也可以对此进行硬编码。

      {
         type: joinaggregate
         fields: [
            startTime
            endTime
         ]
         ops: [
            min
            max
         ]
         as: [
            min
            max
         ]
     }
    
  2. 您想为您的垃圾箱找到一个步骤,您可以稍后对其进行硬编码或使用公式并将其写入新字段。

  3. 您想在数据中创建两个新字段,它们是最大值和最小值之间的序列,另一个是由您的偏移的相同序列。

    {
       type: formula
       expr: sequence(datum.min,datum.max,datum.step)
       as: startBin
    }
    {
       type: formula
       expr: sequence(datum.min + datum.step,datum.max + datum.step,datum.step)
       as: endBin
    }
    
  4. 新字段将是数组。因此,如果我们继续使用展平变换,我们将为每个 bin 中的每个数据值获取一行。

     {
       type: flatten
       fields: [
         startBin
         endBin
       ]
     }
    
  5. 然后您想要计算您的数据跨越每个特定 bin 的总时间。为此,您需要将开始时间向上舍入到 bin 开始,并将结束时间向下舍入到 bin 结束。然后取开始时间和结束时间之间的差异。

     {
       type: formula
       expr: if(datum.startTime<datum.startBin,datum.startBin,if(datum.startTime>datum.endBin,datum.endBin,datum.startTime))
       as: startBinTime
     }
     {
       type: formula
       expr: if(datum.endTime<datum.startBin,if(datum.endTime>datum.endBin,datum.endTime))
       as: endBinTime
     }
     {
       type: formula
       expr: datum.endBinTime - datum.startBinTime
       as: timeInBin
     }
    
  6. 最后,您只需要按 bin 聚合数据并总结这些时间。然后您的数据就可以绘制了。

     {
       type: aggregate
       groupby: [
         startBin
         endBin
       ]
       fields: [
         timeInBin
       ]
       ops: [
         sum
       ]
       as: [
         timeInBin
       ]
     }
    

虽然这个解决方案很长,但在数据的转换部分实施起来相对容易。根据我的经验,它运行得很快,并且显示了 Vega 的多功能性。可视化的自由!