最好举个例子。
让我们说矢量A包括:
A = {3 ,2 ,1 ,4 ,6 ,3 ,8 ,4}
和向量B包括:
B = {1.5,2 ,2 ,1.5,3 ,3 ,3 ,2}
向量B中的唯一值为{1.5, 2, 3}
我希望得到的矢量RESULT为:
RESULT[0] = Average(A given B=1.5) = Average(3,4)
RESULT[1] = Average(A given B=2 ) = Average(2,1,4)
RESULT[2] = Average(A given B=3 ) = Average(6,3,8)
计算此数据的最有效方法是什么。我自己的方法是循环遍历B的唯一元素,并为每个元素循环遍历每个B值,试图匹配该唯一数字,并在每次匹配中保持向量A的相应元素的总结,同时计算匹配的数量,以便我可以找到平均值。
这太慢了。因为我的矢量A是8M元素,矢量B是0.5M唯一值。
任何帮助都将不胜感激。
答案 0 :(得分:3)
这是一个懒惰的想法:以锁步方式遍历两个向量并将结果聚合在一个单独的容器中。例如:
#include <cassert>
#include <cmath>
#include <iostream>
#include <map>
#include <utility>
std::map<double, std::pair<int, std::size_t>> m;
assert(A.size() == B.size());
for (std::size_t i = 0; i != A.size(); ++i)
{
assert(!std::isnan(B[i]));
auto & p = m[B[i]];
p.first += A[i];
p.second += 1;
}
最后,您只需报告结果:
for (const auto & p : m)
std::cout << "Average for bin " << p.first << " is "
<< static_cast<double>(p.second.first) / p.second.second
<< "\n";
(请注意,您的键值不能是NaN:在有序映射中,NaN不是严格排序的一部分;在无序映射中,它不会与自身进行比较。)
答案 1 :(得分:1)
你可以用(哈希)表做一个循环:看到它 Live On Coliru
int main()
{
vector<int> A = {3 ,2 ,1 ,4 ,6 ,3 ,8 ,4};
vector<double> B = {1.5,2 ,2 ,1.5,3 ,3 ,3 ,2};
assert(A.size() == B.size());
struct accum {
uintmax_t sum = 0;
size_t number_of_samples = 0;
void sample(int val) { sum += val; ++number_of_samples; }
};
map<double, accum> average_state;
for(size_t i = 0; i<B.size(); ++i)
average_state[B[i]].sample(A[i]);
for(auto& entry : average_state)
{
accum& state = entry.second;
double average = static_cast<double>(state.sum) / state.number_of_samples;
std::cout << "Bucket " << entry.first << "\taverage of " << state.number_of_samples << " samples:\t" << average << "\n";
}
}
打印
Bucket 1.5 average of 2 samples: 3.5
Bucket 2 average of 3 samples: 2.33333
Bucket 3 average of 3 samples: 5.66667