C++ 如何用迭代器和lambda函数计算标准差
在了解到可以计算存储在C++ 如何用迭代器和lambda函数计算标准差,c++,lambda,iterator,C++,Lambda,Iterator,在了解到可以计算存储在std::vectordata中的数据平均值后,可以通过以下方式完成: void calculate_mean(std::vector<std::vector<double>>::iterator dataBegin, std::vector<std::vector<double>>::iterator dataEnd, std::vector&
std::vectordata
中的数据平均值后,可以通过以下方式完成:
void calculate_mean(std::vector<std::vector<double>>::iterator dataBegin,
std::vector<std::vector<double>>::iterator dataEnd,
std::vector<double>& rowmeans) {
auto Mean = [](std::vector<double> const& vec) {
return std::accumulate(vec.begin(), vec.end(), 0.0) / vec.size(); };
std::transform(dataBegin, dataEnd, rowmeans.begin(), Mean);
}
无效计算平均值(标准::向量::迭代器数据域,
std::vector::迭代器dataEnd,
标准::矢量和行平均数){
自动平均=[](标准::向量常量和向量){
返回std::accumulate(vec.begin(),vec.end(),0.0)/vec.size();};
std::transform(dataegin,dataEnd,rowmeans.begin(),Mean);
}
我做了一个函数,它取数据向量迭代器的开始和结束来计算平均值,std::vector
是我存储结果的地方。
我的第一个问题是,在处理向量时,如何处理函数的返回值。我的意思是,在本例中,我创建了一个别名,并以这种方式修改了在调用此函数之前初始化的向量,因此没有复制回来,这很好。这是一个好的编程实践吗
其次,我的主要问题是,如何调整此函数,以便可以以类似的方式计算每行的标准偏差。我真的很努力,但它只会给一个巨大的混乱,没有什么工作正常。所以,如果有人马上看到了如何做到这一点,我会很高兴,因为我有一个见解。多谢各位
编辑:解决方案
这是我对这个问题的解决方案。给定一个std::vector数据(行,std::vector(列))
,其中数据存储在行中。以下函数同时计算每行的样本标准偏差
auto begin = data.begin();
auto end = data.end();
std::vector<double> std;
std.resize(data.size());
void calculate_std(std::vector<std::vector<double>>::iterator dataBegin,
std::vector<std::vector<double>>::iterator dataEnd,
std::vector<double>& rowstds){
auto test = [](std::vector<double> const& vec) {
double sum = std::accumulate(vec.begin(), vec.end(), 0.0);
double mean = sum / vec.size();
double stdSum = 0.0;
auto Std = [&](const double x) { stdSum += (x - mean) * (x - mean); };
std::for_each(vec.begin(), vec.end(), Std);
return sqrt(stdSum / (vec.size() - 1));
};
std::transform(dataBegin, dataEnd, rowstds.begin(), test);
}
auto begin=data.begin();
自动结束=data.end();
std::向量std;
std.resize(data.size());
void calculate_std(std::vector::iterator dataegin,
std::vector::迭代器dataEnd,
std::矢量和行(std){
自动测试=[](标准::向量常量和向量){
double sum=std::累加(vec.begin(),vec.end(),0.0);
双平均值=总和/向量大小();
双标准差=0.0;
自动标准=[&](常数双x){stdSum+=(x-平均值)*(x-平均值);};
std::for_each(vec.begin()、vec.end()、std);
返回sqrt(stdSum/(向量大小()-1));
};
std::transform(dataegin、dataEnd、rowstds.begin()、test);
}
我测试了一下,效果很好。因此,如果有人有一些改进的建议,请让我知道。这段代码在性能方面是否良好?您会发现,编写函数时通常先使用输入参数,然后使用输入/输出参数。 输出参数(用函数的返回值写入)通常是指向数据的指针或引用。 从这个角度来看,你的解决方案似乎是完美的 资料来源: 我的意思是,在本例中,我创建了一个别名,并以这种方式修改了在调用此函数之前初始化的向量,因此没有复制回来,这很好。这是一个好的编程实践吗 否,您应该使用本地
向量变量并按值返回。任何值得使用的编译器,以及任何符合C++11标准的编译器,如果出于任何原因不能完全删除复制/移动,都需要执行移动
您编写的代码对调用方施加了不明显的额外要求。例如,rowmeans
必须包含足够的元素来存储平均值或未定义的行为结果。对于第二部分-“我非常努力,但它只会造成一个巨大的混乱,没有正常工作。”-向我们展示您的尝试。@T.C我用我的一次尝试进行了编辑,以找出它是如何工作的。这真是一团糟,所以我想我还是不发布它为好。我投票结束这个问题,因为它是关于代码审查的,属于codereview.stackexchange.com