计算数据的平均值
Calculating the mean of the data
/***************************************************************************
Description : Calculates the trimmed mean of the data.
Comments : trim defaults to 0. Trim = 0.5 now gives the median.
***************************************************************************/
Real StatData::mean(Real trim) const
{
check_trim(trim);
if (size() < 1)
err << "StatData::mean: no data" << fatal_error;
Real result = 0;
const_cast<StatData&>(*this).items.sort();
int low = (int)(size()*trim); // starting at 0
int high = size() - low;
if (low == high) {
low--; high++;
}
for(int k = low; k < high; k++)
result += items[k];
ASSERT(2*low < size()); // Make sure we're not dividing by zero.
return result / (size() - 2*low);
}
我有三个问题要问:
1) *this
是否指StatData?
2)为什么ASSERT(2*low < size())
要检查是否除零?
3)平均值通常是指总金额除以总规模。但是我们为什么要做size()-2*low
呢?
在我们开始之前,让我们花一点时间来解释参数trim
是什么。
trim
表示在你想要计算你需要的数据之前,你想要从数据的两端切断多少数据的分数,假设这是有序的。通过执行trim = 0.5
,您将切断除考虑中间之外的所有内容,这是中位数。例如,通过执行trim = 0.1
,前10%和后10%的数据被丢弃,并且您只计算剩余80%数据的平均值。注意,这是[0,1]
之间的规范化分数。然后将这个分数乘以size()
,以确定在计算平均值时我们需要从数据中的哪个索引开始(用low
表示),以及在哪个索引处停止(用high
表示)。high
简单地由size() - low
计算,因为两边要切断的数据量需要是对称的。这实际上有时被称为alpha裁剪平均值,或者更常见的是截断平均值。它也被称为alpha裁剪平均值的原因是因为alpha定义了你想要从排序数据的开始和结束处切断多少分数。同样在我们的例子中,alpha = trim
.
现在回答你的问题。
<标题>问题# 1
*this
引用当前类的实例,该实例的类型为StatData
,并最终试图访问items
,这似乎是一个包含Real
类型的一些数字的容器。然而,正如尼尔·柯克在他的评论中解释的那样,这是使用const_cast
的一种非常不安全的方式,所以你可以访问items
,这样你就可以对这些项目进行排序。这是非常糟糕。
> 2*low
,因为数据的大小永远不会超过这个点。他们检查是否size() < 2*low
,以确保您将数据的总和除以数字> 0
,这是我们从算术平均值中期望的。如果这个条件失败,这意味着计算平均值是不可能的,它应该输出一个错误。
<标题>问题# 3 你除以size() - 2*low
,因为你使用trim
来丢弃从开始到结束你不需要的数据的比例。这正好对应于一边的low
和另一边的low
。请注意,high
计算中我们需要在上端停止累积,并且在此点之后存在的数据比例为low
。因此,这些被消除的比例的组合是2*low
,这就是为什么您需要从size()
中减去它,因为您不再使用该数据。
该函数被标记为const
,因此开发人员使用了一个相当难看的const_cast
来强制转换const以调用sort
。
ASSERT
似乎是一个宏(因为它是大写字母),它很可能调用assert,如果表达式的计算结果为零,则终止程序。
trimmed mean
含义的概要,请参阅本页。
10%修剪平均值是通过排除最大的10%计算得出的平均值取样本中最小值的10%取算术平均值在剩下的80%的样本中…
- 防止主数据类型C++的隐式转换
- 计算数组c++的平均值
- 用于访问容器<T>数据成员的正确 API
- 嵌套在类中时无法设置成员数据
- 使用流处理接收到的数据
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在cuda线程之间共享大量常量数据
- C++将文本文件中的数据读取到结构数组中
- 如何在C++中序列化结构数据
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 在c代码之间共享数据的最佳方式
- 链表,反向函数,数据结构
- 数据成员SFINAE的C++17测试:gcc vs clang
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 计算用于CAFFE分类的HDF5数据集的平均值
- Arduino HC-SR04 传感器,平均值数据
- 快速的数据结构或算法来找到图像堆栈中每个像素的平均值
- 计算数据的平均值