简体   繁体   English

boost :: accumulators :: statistics的中值输出令人困惑

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM