【问题标题】:Calculate histogram from a set of data using the standard library or the boost library使用标准库或 boost 库从一组数据中计算直方图
【发布时间】:2018-03-23 21:42:31
【问题描述】:

我的问题很简单。我有一个带有随机值的浮点数组。我想找出数组中值的出现次数。

例如。

float data[] = {1.1,1.1,1.1,
              2.1,2.1,2.1,
              3.1,3.1,3.1,
              4.1,4.1,4.1,
              5.1,5.1,5.1,
              1.5,1.5,1.5,
              3.2,3.2,3.2};

标准库或 boost 库中是否有某种范围直方图函数可以返回值的出现次数。在上面的例子中,

0-1 -> 0 times
1-2 -> 6 times
2-3 -> 3 times
3-4 -> 6 times
4-5 -> 3 times

【问题讨论】:

  • AFAIK 标准库中没有直接的直方图函数。您可以使用地图来跟踪计数,如图所示here
  • 出于好奇,这是一道面试题吗?
  • @Ron 不,我正在尝试在像 faerneback 这样的密集光流算法中找到位移矢量的出现次数。
  • @infoclogged 对我来说都是希腊语,但感谢您的澄清。

标签: c++


【解决方案1】:

您正在寻找能够满足您需求的std::map

std::vector<double> data = {1.1,1.1,1.1,
              2.1,2.1,2.1,
              3.1,3.1,3.1,
              4.1,4.1,4.1,
              5.1,5.1,5.1,
              1.5,1.5,1.5,
              3.2,3.2,3.2};

std::map<int,int> histogram;

for (const auto& e : data) ++histogram[e];

for (const auto& x : histogram) std::cout << x.first << " " << x.second <<"\n";

打印:

1 6
2 3
3 6
4 3
5 3

我允许自己使用 vector 而不是 c 数组。映射存储键值对,其operator[] 返回对给定键值的引用(如果还没有,则默认构造它)。

【讨论】:

  • 如果我需要{[0.0,1.5] , [1.5,3.0] , [3.0,4.5] , [4.5,6.0]}之间的计数怎么办?
  • @yellow01 这就是问题所在。对于任意间隔,您需要更多。将区间起点存储在一个向量中(当没有孔时,您不需要起点和终点)然后为每个数据点确定它落在哪个区间(例如通过std::upper_bound),然后使用地图进行计数
【解决方案2】:

使用count 怎么样。而这个可行的解决方案:

int count(std::vector<float> &data, const float lower, const float upper) {
    return std::count_if(data.begin(), data.end(),[&lower, &upper](float i){return i>lower && i<upper;});
}

【讨论】:

  • 使用这个 OP 必须遍历每个间隔的输入
【解决方案3】:

为了补充已接受的答案,只要您对数据数组进行排序,也可以计算任意间隔的直方图。

std::vector<double> data = {1.1,1.1,1.1,
                            2.1,2.1,2.1,
                            3.1,3.1,3.1,
                            4.1,4.1,4.1,
                            5.1,5.1,5.1,
                            1.5,1.5,1.5,
                            3.2,3.2,3.2};

std::sort(data.begin(), data.end());

std::map<double, int> histogram;

double bin = 0; //Choose your starting bin
const double bin_width = 1.5; //Choose your bin interval
for (const auto& e : data)
{
    e >= bin + bin_width ? bin += bin_width : false;
    ++histogram[bin];
}

for (const auto& x : histogram) 
{
    std::printf("[%.2f,%.2f[ : %d\n", x.first, x.first + bin_width, x.second);
}

打印:

[0.00,1.50[ : 3
[1.50,3.00[ : 6
[3.00,4.50[ : 9
[4.50,6.00[ : 3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 2017-10-11
    • 2014-09-21
    • 2011-09-17
    • 2011-08-12
    • 2019-09-18
    相关资源
    最近更新 更多