C++多维vector计算标准差时lambda访问列均值的问题咨询
C++ 列标准差计算修正方案
核心问题说明
lambda 完全支持访问已捕获的外部 vector,你当前的错误是没有正确获取当前元素对应的列索引:inputMean[row]的写法非法,row是当前行的std::vector<float>对象,不能作为索引下标使用。
修正后代码(保留for_each+transform格式)
// 计算均值部分的代码保持不变即可,注意完成均值计算后inputMean已存储各列的均值 std::vector<float> inputSTD(targetInputs[0].size(), 0.0f); // 初始化标准差累加值为0,避免垃圾值影响 size_t rowCount = targetInputs.size(); std::for_each(targetInputs.begin(), targetInputs.end(), [&](const std::vector<float>& row) { size_t colIdx = 0; // 跟踪当前处理的列索引 std::transform(row.begin(), row.end(), inputSTD.begin(), inputSTD.begin(), [&](float rowVal, float curSumSq) { float diff = rowVal - inputMean[colIdx]; colIdx++; // 处理完当前列,索引自增 return curSumSq + diff * diff; }); }); // 计算最终标准差,二选一即可 // 1. 总体标准差(数据为全部统计对象时使用) std::transform(inputSTD.begin(), inputSTD.end(), inputSTD.begin(), [rowCount](float sumSq) { return sqrt(sumSq / rowCount); }); // 2. 样本标准差(数据为抽样样本时使用) // std::transform(inputSTD.begin(), inputSTD.end(), inputSTD.begin(), // [rowCount](float sumSq) { return sqrt(sumSq / (rowCount - 1)); });
关键逻辑说明
- 我们在
transform外层定义列索引变量colIdx,每处理一行内的一个元素就自增1,刚好匹配当前元素对应的列位置,就能准确取到inputMean中对应列的均值。 - 必须在定义
inputSTD时就初始化为0,否则默认初始化的float值是不确定的,累加结果会出错。 - 原代码中
transform的二元函数参数顺序有误:第一个参数是行元素值,第二个参数是inputSTD中存储的当前平方和累加值,你之前写反了二者的位置,会导致计算逻辑错误。
内容的提问来源于stack exchange,提问作者JungSoo Ok
相关产品推荐
相关产品推荐

