代码之家  ›  专栏  ›  技术社区  ›  user2924127

时间序列数据-统计两组数据的出现次数

  •  0
  • user2924127  · 技术社区  · 6 年前

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

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

    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 ?

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

    1 回复  |  直到 6 年前
        1
  •  2
  •   btilly    6 年前

    考虑到您正在尝试生成的大量结果,我建议您寻找微优化和划分工作的方法。没有一种花哨的方法来减少操作,只要让它们高效。

    因此,我建议您将字节数组转换为 BitSet 你的4个计数应该通过 cardinality() a.and(b) (1,1) a.andNot(b) (1,0) a.or(b).flip() (0,0)和 a.flip().and(b) (0,1)。在同步工作方面,您应该将工作分配为20个数组和20个数组的块(用这个图进行实验)的所有成对组合。一个足够大的工作块来做真正的工作。一个足够小的描述源并产生相当小的消息。每件工作都应该由一个工人进行单螺纹加工。仔细考虑如何存储最终数据-您的许多工作将构建该数据结构。无论如何要避免的是一个基于哈希的数据结构,它使您可以在内存中的任意位置进行搜索。更好的方法是在适当的位置对数据进行排序。

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