[英]the median output of boost::accumulators::statistics is confusing
When I was using boost::accumulators::statistics to calculate the median for an array, I got the below code and result: 当我使用boost :: accumulators :: statistics计算数组的中位数时,我得到了以下代码和结果:
accumulator_set< double, features< tag::mean, tag::median > > acc;
acc(2);
acc(1);
acc(3);
value = mean( acc ); //output is 2, expected
value = median( acc ); //output is 3, unexpected
I think the result for value = median( acc )
should be 2. 我认为
value = median( acc )
应为2。
accumulator_set
doesn't actually store all of the values. accumulator_set
实际上并不存储所有值。 Every call to acc(double)
actually calls something like acc.mean_accumulator(double); acc.median_accumulator(double)
每次对
acc(double)
调用实际上都会调用acc.mean_accumulator(double); acc.median_accumulator(double)
类的东西acc.mean_accumulator(double); acc.median_accumulator(double)
acc.mean_accumulator(double); acc.median_accumulator(double)
, and it tries not to store all the values. acc.mean_accumulator(double); acc.median_accumulator(double)
,它尝试不存储所有值。
For median
, a P^2 quantile estimator is used. 对于
median
,使用P ^ 2分位数估计量。 ( See here ) It is only an estimate, and if you do: ( 请参阅此处 )这只是一个估计,如果您这样做:
acc(4);
acc(1);
acc(2);
acc(0);
acc(3);
it returns the expected 2
. 它返回预期的
2
。
If you want an exact value and have a small number of data values, use a function like this: 如果您需要一个确切的值并且数据值很少,请使用如下函数:
#include <algorithm>
#include <vector>
// Warning: Will swap elements in the range.
// `It` needs to be a non-const random access iterator
// (Like `T*`)
template<class It>
auto median(It first, It last) {
auto size = last - first;
if (size % 2 == 1U) {
std::nth_element(first, first + (size / 2U), last);
return *(first + (size / 2U));
}
std::nth_element(first, first + (size / 2U), last);
auto&& high = first + (size / 2U);
auto&& low = std::max(first, first + (size / 2U - 1U));
return (*low + *high) / 2;
}
// Copies the range and modifies the copy instead
template<class It>
auto const_median(It first, It last) {
std::vector<decltype(*first)> v(first, last);
return median(v.begin(), v.end());
}
int main() {
std::vector<double> v{2, 1, 3};
std::cout << median(v.begin(), v.end()) << '\n';
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.