对相关数组进行排序/组合

时间:2011-04-19 22:09:47

标签: arrays sorting merge fuzzy-comparison

必须有一些算法能让这比我正在做的更容易......

我所拥有的是两个数组,每个数组都有两列。两者中的一列是时间戳,另一列是测量值。

需要做的是将其转换为单个数组:timestamp,measurement1,measurement2

问题是时间戳通常不会完全匹配。一个数组可能在一段时间内完全丢失一个值,或者时间戳可能关闭的数量微不足道(不足以将两个测量值分配给相同的时间戳)。

有一些众所周知的做这种模糊合并操作的方法吗?一个简单的公共域函数??

1 个答案:

答案 0 :(得分:1)

首先问自己这些问题:数组是否具有相同数量的元素?您想如何组合具有相同时间戳的两个项目?您想如何组合两个具有不同时间戳的项目?

您可能必须自己编写算法。这样的事情很容易实现:

  1. 首先按时间戳顺序对每个数组进行排序。
  2. 分别在每个输入数组的开头声明两个迭代器,以及一个空的输出数组。
  3. 然后,检查哪个阵列具有最早的时间戳。称之为EARLY,另一个是LATE。
    • 如果EARLY接近LATE(小于某个常量),则应用合并操作并将结果插入输出数组的末尾。增加两个迭代器并返回到3。
    • 否则,EARLY远离LATE。您需要在LATE数组中处理缺失值,可能是重复前一个值或使用某个函数进行插值。决定在输出数组中插入或不插入值。在这种情况下,您只需递增EARLY数组迭代器,然后返回3.
  4. 如果到达任何一个数组的末尾,则另一个数组的其余部分为LATE。您可能希望将其解释为缺失值,并重复或插入测量值。
  5. 返回输出数组。
  6. OutputArray merge(InputArray& a, InputArray& b) {
        InputArray::iterator a_it = a.begin();
        InputArray::iterator b_it = b.begin();
        while(a_it != a.end() && b_it != b.end()) {
            InputArray::iterator& early = *a_it.timestamp < *b_it.timestamp ? a_it : b_it;
            InputArray::iterator& late = *a_it.timestamp < *b_it.timestamp ? b_it : a_it;
            if(*late.timestamp - *early.timestamp < TIMESTAMP_CLOSE_ENOUGH) {
                output.timestamp = (*late.timestamp + *early.timestamp) / 2; // mean value
                output.measure1 = *a_it.measure;
                output.measure2 = *b_it.measure;
                outputArray.push_back(output);
                a_it++; b_it++;
            }
            else {
                output.timestamp = *early.timestamp;
                output.measure1 = *a_it.timestamp < *b_it.timestamp ? *a_it.measure : outputArray.back.measure1; // previous value if missing
                output.measure2 = *a_it.timestamp < *b_it.timestamp ? outputArray.back.measure2 : *b_it.measure;
                outputArray.push_back(output);
                early++;
            }
        }
    
        InputArray::iterator& late = a_it != a.end() ? a_it : b_it;
        InputArray::iterator late_end = a_it != a.end() ? a.end() : b.end();
        while(late != late_end) {
                output.timestamp = *late.timestamp;
                output.measure1 = a_it != a.end() ? *a_it.measure : outputArray.back.measure1; // previous value if missing
                output.measure2 = a_it != a.end() ? outputArray.back.measure2 : *b_it.measure;
                outputArray.push_back(output);
                late++;
        }
        return outputArray;
    }