时间序列数据-统计两个集合的出现次数



我有时间序列数据。内部数据的值为1或0(可以是true或false,也可以是任何其他二进制表示)。

例如,我有两个时间序列数据变量:

byte[] a1 = new byte[]{1,0,0,1,0};
byte[] a2 = new byte[]{1,1,1,0,1};

我现在比较这两个数组来计算组合发生的次数:

Map<String,Integer> count = new HashMap<String,Integer>();
//all the time series arrays have the same length. In real life each would timeseries array would have a length of about 100
for(int i=0; i<ai.length(); i++){
//a1[i] and a[2] occured. If this keys exists incremnt the count by one, otherwise insert the new key
count.merge(a1[i]+":"+a2[i], 1, Integer::sum)
}

本质上,我要寻找的输出是当a1 = 1时,a2 = 1是多少次,a2 = 0是多少次?同样,当a1 = 0时,a2 = 1是多少次,a2 = 0是多少次?

我面临的问题是,我在我的程序中进行了数十亿次这样的比较。完成的时间比我想要的要长得多。我知道这需要很长时间才能完成,但我想知道是否有其他方法可以更快地实现它(我已经在使用多线程,我正在更多地研究算法的变化、数据结构的变化、开源库等)?

鉴于您正在尝试产生大量结果,我建议您寻找微观优化和划分工作的方法。没有什么奇特的方法可以减少操作,只是让它们变得高效。

因此,我建议您将字节数组转换为BitSets。您的4个计数应通过在a.and(b)(1,1)、a.andNot(b)(1,0)、a.or(b).flip()(0,0)和a.flip().and(b)(0,1)上执行cardinality()来完成。在同步工作方面,您应该将工作分配为块的所有成对组合(用这个图进行实验),比如20个阵列和20个阵列。一个足够大的工作块成为真正的工作。一个小到足以描述来源并导致相当小的消息的消息。每件工作都应该由一名工人进行单线程处理。仔细考虑如何存储最终数据——你的很多工作都将是构建数据结构。要不惜一切代价避免的是一种基于哈希的数据结构,它会导致你在内存中寻找所有随机的位置。对数据进行适当排序要好得多。

如果可以,请关注缓存一致性。

最新更新