C++计算方差和标准差,适用于所有容器和数组

一、方差和标准差的定义

  方差是各样本值与均值之差的平方值的平均数。标准差是方差的算术平方根。
  标准差/方差反映一个数据集的离散程度。标准差/方差越大,表示数据的波动越大;标准差/方差越小,表示数据的波动越小。

二、关键代码

// 计算均值
auto size = std::distance(first, last); // 两个迭代器/指针之间的距离,即样本数量
double avg = std::accumulate(first, last, 0.0) / size;

// 计算方差
double variance(0);
std::for_each(first, last, [avg, &variance](const ValueType &num) { variance += (num - avg) * (num - avg); });
variance /= size;

// 计算标准差
auto standardDeviation = std::sqrt(variance);

三、代码示例

1)utils.h

/*
 * Copyright (c) 2023 All rights reserved
 * Filename:    utils.h
 * Brief:       工具函数
 * Depend:      C++14
 *
 * Version:     V1.0.0
 * Date:        2023/03/07
 * Author:      LucianY(https://blog.csdn.net/LucainY)
 * Note:        初次版本。
 * 
 */
 
#include <cmath>

#include <algorithm>
#include <numeric>
#include <type_traits>

#ifndef LY_UTILS_H
#define LY_UTILS_H

namespace Ly {

//! 计算方差
template<typename ForwardIt>
inline double ComputeVariance(ForwardIt first, ForwardIt last)
{
    using ValueType = typename std::iterator_traits<ForwardIt>::value_type;
    auto size = std::distance(first, last);
    if (size <= 1) { // 样本数量小于或等于1时,直接返回0
        return 0;
    }

    double avg = std::accumulate(first, last, 0.0) / size; // 计算均值
    double variance(0);
    std::for_each(first, last, [avg, &variance](const ValueType &num) { variance += (num - avg) * (num - avg); });
    return variance / size;
}

//! 计算标准差
template<typename ForwardIt>
inline double ComputeStandardDeviation(ForwardIt first, ForwardIt last)
{
    return std::sqrt(ComputeVariance(first, last));
}

} // namespace Ly
#endif // LY_UTILS_H

2)main.cpp

/*
 * Copyright (c) 2023 All rights reserved
 * Filename: main.cpp
 * Author: LucianY(https://blog.csdn.net/LucainY)
 * Brief: 方差/标准差计算函数测试
 */

#include <cstdio>
#include <vector>

#include "utils.h"

using namespace Ly;

void Test()
{
    //! 容器
    std::vector<int> nums{ 1, 2, 3 };
    printf("nums variance: %lf\n", ComputeVariance(nums.begin(), nums.end()));
    printf("nums standard deviation: %lf\n", ComputeStandardDeviation(nums.begin(), nums.end()));

    //! 栈数组
    float nums2[5]{ 1, 2, 3, 5, 7 };
    printf("nums2 variance: %lf\n", ComputeVariance(std::begin(nums2), std::end(nums2)));
    printf("nums2 standard deviation: %lf\n", ComputeStandardDeviation(std::begin(nums2), std::end(nums2)));

    //! 堆数组
    constexpr int size = 7;
    double *nums3 = new double[size]{ 1, 2, 3, 5, 7, 11, 13};
    printf("nums3 variance: %lf\n", ComputeVariance(nums3, nums3 + size));
    printf("nums3 standard deviation: %lf\n", ComputeStandardDeviation(nums3, nums3 + size));
    delete[] nums3;
}

int main()
{
    Test();
    getchar();
    return 0;
}

3)测试输出

nums variance : 0.666667
nums standard deviation : 0.816497
nums2 variance : 4.640000
nums2 standard deviation : 2.154066
nums3 variance : 18.000000
nums3 standard deviation : 4.242641

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值