缓存时间序列差分的聚合数据

7

有没有可能预先计算(缓存)差异信号的聚合值(最小/最大/平均值)?

我有几个通道(例如50个),每秒钟进行一次或多次测量,我可以轻松地存储预先计算的1分钟或15分钟聚合值以加快显示速度。

但是其中一个要求是显示相对值的图表。例如,如果我有通道C1、C2和C3,则用户希望在单独的图表上看到C1的平均值和(C2-C3)的平均值(或15分钟的最小/最大值)。

例如,假设我有这两个通道(还有48个):

t(min)    0    +1   +2   +3   +4   +5   +6   +7   +8   +9   +10
C1       0.0  0.1  0.2 -0.1  0.0  0.1  0.3  0.5  0.7  0.9  0.2
C2       0.1  0.4  0.2  0.1 -0.1  0.5  0.6  0.1  0.2  0.3  0.0

我可以预先计算并存储5分钟的聚合数据:
t(min)    0 to +4    +5 to +10
C1_min     -0.1         0.1
C1_max      0.2         0.9
C2_min     -0.1         0.0
C2_max      0.4         0.6

从中可以轻松获取10分钟或15分钟的总计。

但是,如果用户想要查看任何这50个通道组合的min(C2-C1)max(C2-C1) 5分钟聚合数据,似乎我不能重复使用此信息。

换句话说,除了存储这些元组的每个可能组合之外,在我的看来似乎不可能预先计算出这些值,因为min(C2-C3)并不等于min(C2)-min(C3)

我是否漏掉了某些能帮助我更快地计算这些值的想法?


我认为提供样例数据和期望结果会有所帮助。 - Gordon Linoff
@GordonLinoff:我更新了问题,希望这样会更清晰一点。 - Lou
2
我认为你对min和max的理解是正确的(考虑两个完全相同的信号,它们的差值将为零)。然而平均值是可以的,ave(A-B) = ave(A)-ave(B) (参见http://math.stackexchange.com/questions/1360311/why-is-the-average-of-a-sum-equal-the-sum-of-the-averages) - danh
@danh:直到现在我才意识到这个关于平均数的问题,但它非常有道理,感谢你提供的有用链接!我仍然不确定是否有任何方法可以加速min(A-B)聚合(即避免每次都要遍历整个数据库)。我问题中的示例是简化的,但实际上每秒钟有很多测量值,而“差异最小值”的要求确实破坏了我对快速绘图的希望。 - Lou
2
如果近似值足够好,您可以使用max(A)-min(B)获得max(A-B)的上限,并使用min(A)-max(B)获得下限。 如果它们相等,那么您就得到了答案!(虽然不太可能 - 这意味着在该时间间隔内A和B都没有改变。)如果上限和下限至少接近,那么您就可以以某种“精度”知道答案。 - j_random_hacker
显示剩余4条评论
1个回答

1
You would simply need to have all the data of C2 and C3 to get the aggregation min(C2-C3).
However, if your goal is to minimize the data required to do this calculation, I suggest you do it in the following way (this solution will require dealing with big numbers - depending on the number of channels).
If you know all channels will not have values that exceeds a certain value (let's say it's 10) then we can combine all the channels' data in 1 channel, let's name it C.
To calculate C:
C = (C1 * 10^1) + (C2 * 10^2) + (C3 * 10^3) + .. + (Cn * 10^n).

你最终会得到一个包含所有通道值的通道C。
然后,要计算某一点上两个通道之间的差异,你只需要在运行时从C中“提取”这两个通道的值。
C1 = floor((C mod 10^1) / 10^(1-p)) / 10^p
C2 = floor((C mod 10^2) / 10^(2-p)) / 10^p
...
Cn = floor((C mod 10^n) / 10^(n-p)) / 10^p

其中p是提取通道值的十进制精度。

在这种情况下,使用预先计算的C计算两个通道xy之间的差异将会是:

min(Cy-Cx) = min((floor((C mod 10^y) / 10^(y-p)) / 10^p) - (floor((C mod 10^x) / 10^(x-p)) / 10^p))

接着,您可以在一段时间内汇总这些值。希望能对您有所帮助。


但这仍然意味着我需要读取每个单独的 C,而且每个 C 至少与所有通道的总和一样大。这意味着我将以更多的数据方式读取数据(虽然表访问次数较少,但数据总量更大)。 - Lou
这当然取决于您的资源限制,如果是这种情况,C将是一个很大的数字,但是您只需要在预计算阶段计算一次,同时还要计算最小值和最大值。 但是,当您想生成差异聚合时,您不需要访问聚合期间所有通道数据,只需要访问相应时间槽的C值即可。 - Abed Hawa
所以以您的例子为例:如果您有50个通道,这将节省您循环遍历所有这些通道数据的时间,并允许您通过仅访问“C”值来获取差异。您的内存大小是否受限制? - Abed Hawa
这些值存储在几个数据库表中。我无法定义“最大值”(而且我认为这种简单的加法方法不能处理负值)。因此,将多个表放入一个表中的唯一方法是对它们进行二进制连接(即,4个浮点数必须存储到16个字节中),因此我需要读取的数据总量与分别读取每个表时相同。 - Lou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接