c++中如何计算标准差与方差_c++数学计算统计函数


最稳妥方式是用std::accumulate两遍遍历:先求均值,再算平方偏差均值;样本方差除以n-1,总体方差除以n;需预检查NaN/inf、空容器及分母为零。

std::accumulate 手动计算方差和标准差最稳妥

标准库没有内置的方差或标准差函数,std::valarray 虽有 sum() 但不支持直接求均值平方差;依赖第三方库(如 Boost.Math)会增加构建复杂度。实际项目中,用 std::accumulate 两遍遍历是最可控的方式:第一遍算均值,第二遍算平方偏差均值。

  • 必须先求平均值 mean,再遍历计算 (x - mean) * (x - mean),不能合并成单次 accumulate —— 否则会因浮点精度丢失导致方差为负(尤其数据量大、数值集中时)
  • 样本方差用 n-1 作分母(贝塞尔校正),总体方差用 n;C++ 里需显式判断并传入 ddof = 01
  • 输入容器应为 std::vector 或类似可迭代浮点序列,避免整数除法截断
#include 
#include 
#include 

double variance(const std::vector& data, int ddof = 0) { if (data.empty()) return 0.0; double mean = std::accumulate(data.begin(), data.end(), 0.0) / data.size(); double sum_sq_diff = std::accumulate(data.begin(), data.end(), 0.0, [mean](double acc, double x) { return acc + (x - mean) * (x - mean); }); return sum_sq_diff / (data.size() - ddof); }

double stddev(const std::vector& data, int ddof = 0) { return std::sqrt(variance(data, ddof)); }

std::valarray 快速原型但慎用于生产

std::valarray 支持向量化运算,写起来简洁,但存在隐式拷贝开销、不支持迭代器、且部分老编译器(如 MSVC 2015 前)实现不全。仅建议在小规模数据、快速验证公式时使用。

  • valarraysum() 返回 double,但中间运算可能触发 promotion 规则,若原始类型是 float,结果仍可能是 float,导致精度不足
  • 无法直接对 valarray 做“减去标量均值”操作而不生成临时对象,内存效率不如手写循环
  • 以下写法看似短,但每次 - mean 都构造新 valarray,不适用于大数据集
#include 
#include 

double variance_valarray(const std::valarray& v) { if (v.size() == 0) return 0.0; double mean = v.sum() / v.size(); std::valarray diff = v - mean; return (diff * diff).sum() / v.size(); }

遇到 nan 或负方差?检查输入和溢出路径

调用后得到 nanvariance 返回负值,几乎一定是以下原因:

  • 输入含 NaNinf:用 std::isnan(x)std::isinf(x) 预过滤,否则 (x - mean) 可能传播 nan
  • 数据范围过大导致 (x - mean) * (x - mean) 溢出 double(如 x ≈ 1e155),此时应改用 Welford 在线算法避免大数相减
  • 容器大小为 1 且 ddof = 1 → 分母为 0 → 返回 inf;需在函数开头加 if (data.size()

性能敏感场景用 Welford 算法单趟完成

当数据来自流式输入(如传感器、文件逐行读取)、不能存全量或内存受限时,Welford 方法可在一次遍历中累积计算方差,且数值稳定性优于两遍法。

  • 核心是维护 Mk(当前均值)和 Sk(平方和修正项),递推更新,无须存储全部数据
  • 最终方差为 S / (n - ddof),其中 S 是递推得到的 Sk
  • 注意:初始 M = 0.0, S = 0.0, n = 0,每来一个 x 更新一次,n 从 1 开始计数
struct Welford {
    double M = 0.0, S = 0.0;
    size_t n = 0;
void add(double x) {
    n++;
    double delta = x - M;
    M += delta / n;
    S += delta * (x - M);
}

double variance(int ddof = 0) const {
    return n <= static_castzuojiankuohaophpcnsize_tyoujiankuohaophpcn(ddof) ? 0.0 : S / (n - ddof);
}

double stddev(int ddof = 0) const {
    return std::sqrt(variance(ddof));
}

};

Welford 算法的数值稳定性常被低估——它真正难处理的是极端情况:比如所有数都接近 1e308,此时 delta 计算仍可能失真。这种时候,要么换更高精度类型(long double),要么做预平移(减去估计均值再算)。


# 大数据  # c++  # 标准库  # Float  # if  # math  # double  # 循环  # 对象  # 算法  # 传感器  # 均值  # 遍历  # 浮点  # 两遍  # 平方和  # 的是  # 标准差  # 迭代  # 而不  # 可在 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化76771 】 【 技术知识130152 】 【 IDC云计算60162 】 【 营销推广131313 】 【 AI优化88182 】 【 百度推广37138 】 【 网站推荐60173 】 【 精选阅读31334


相关推荐: Python迭代器生成器进阶教程_节省内存与懒加载实战  Win11如何设置省电模式 Win11开启电池节电功能【优化】  电脑的“网络和共享中心”去哪了_Windows 11新版网络设置指南【新手】  c++的static关键字有什么用 静态变量和静态函数的应用场景【教程】  如何使用Golang搭建Web开发环境_快速启动HTTP服务  如何解决Windows字体显示模糊的问题?(ClearType设置)  如何使用Golang开发简单的聊天室消息存储_Golang WebSocket数据持久化方法  Win11怎么设置快速访问_Windows11文件资源管理器主页  Win11文件扩展名怎么显示_Win11查看文件后缀名设置【基础】  Python函数接口文档化_自动化说明【指导】  ACF 教程:正确更新嵌套在多层 Group 字段内的子字段  Win11右键反应慢怎么办 Win11优化右键菜单加载速度【技巧】  Python字符串操作教程_切片拼接与格式化详解  如何使用Golang实现容器自动化运维_Golang Docker运维管理方法  Python性能剖析高级教程_cProfileLineProfiler优化案例解析  Mac怎么安装软件_Mac安装dmg与pkg文件的区别【指南】  Python异步编程高级项目教程_asyncio协程任务管理实战  Python与GPU加速技术_CUDA与Numba高性能计算实践  如何使用Golang管理模块版本_Golanggo mod tidy与升级方法  Python高性能计算项目教程_NumPyCythonGPU并行加速  Linux如何安装JDK11_Linux环境变量配置与Java开发环境搭建【教程】  Win11怎么开启远程桌面连接_Windows11系统属性远程设置  Win10怎样卸载iTunes_Win10卸载iTunes步骤【步骤】  Win10路由器怎么隐藏ssid Win10隐藏wifi名称设置【指南】  Win11怎么设置触控板手势_Windows11三指四指操作自定义  Win10怎样卸载自带Edge_Win10卸载Edge浏览器步骤【教程】  c++20的std::format怎么用 比printf更安全高效的格式化方法【详解】  c++怎么设置线程优先级与cpu亲和性_c++ 多核处理器性能绑定【指南】  Windows 10怎么录屏_Windows 10使用Xbox Game Bar录制屏幕视频教程  c++如何使用std::bind绑定函数参数_c++ 占位符std::placeholders使用【详解】  如何使用Golang实现基本类型比较_Golang比较操作符使用方法  如何使用Golang构建基础消息队列模拟_Golang消息发送与消费实现方法  MAC如何隐藏文件夹及文件_MAC终端命令隐藏与第三方工具加密【教程】  C++中的协变与逆变是什么?C++函数指针与返回类型详解【类型系统】  英国搜索:多数英国人认为语言搜索是未来搜索  Windows Defender扫描失败怎么办_安全模块损坏修复方式  Win11无法安装软件怎么办_Win11解除应用安装限制设置【修复】  Win11触摸板没反应怎么办_开启Win11笔记本触摸板手势教程【步骤】  Win11怎么设置ipv4地址_Windows 11固定静态IP地址配置教程【详解】  如何使用正则表达式提取以编号开头、后接多个注解的逻辑分组块  php485函数执行慢怎么优化_php485性能提升小技巧【技巧】  Windows系统被恶意软件破坏后的恢复策略_错误提示修复方式  Win11怎么关闭搜索历史_Win11清除设备上的搜索历史记录  Python随机数生成_random模块说明【指导】  php能控制zigbee模块吗_php通过串口与cc2530 zigbee通信【介绍】  Mac上的iMovie如何剪辑视频?(新手入门教程)  如何高效删除 NumPy 二维数组中所有元素相同的列  Win11怎么清理C盘系统错误报告_Win11清理系统错误报告技巧【教程】  Mac电脑进水了怎么办_MacBook进水后紧急处理方法【必看】  如何在 ACF 中正确更新嵌套多层的 Group 字段子字段 

 2026-01-04

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

致胜网络推广营销网


致胜网络推广营销网

致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 915688610

 17370845950

 915688610@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.