如何在直方图上进行对数合并?

How to do logarithmic binning on a histogram?

我正在寻找一种以对数方式对某些数据集进行分箱的技术。我们得到的数据的值范围从 _min_max (浮点数 >= 0),用户需要能够指定一个不同的数字bins _num_bins(一些整数 n)。

我已经实施了取自 this question and some help on scaling here 的解决方案,但当我的数据值低于 1.0 时,我的解决方案停止工作。

class Histogram {
double _min, _max;
int _num_bins;
......
};

double Histogram::logarithmicValueOfBin(double in) const {
    if (in == 0.0)
        return _min;

    double b = std::log(_max / _min) / (_max - _min);
    double a = _max / std::exp(b * _max);

    double in_unscaled = in * (_max - _min) / _num_bins + _min;
    return a * std::exp(b * in_unscaled) ;
}

当数据值都大于 1 时,我得到大小合适的 bin 并且可以正确绘制。当值小于 1 时,箱子的大小大致相同,我们得到的箱子太多了。

我通过重新实现 opensource version of Matlab's logspace function 找到了解决方案。

给定一个范围和多个 bin,您需要创建一个均匀间隔的数字序列

module.exports = function linspace(a,b,n) {
  var every = (b-a)/(n-1),
      ranged = integers(a,b,every);

  return ranged.length == n ? ranged : ranged.concat(b);
}

之后您需要遍历每个值并使用您的基数(最有可能是 e、2 或 10)存储功率并获得您的 bin 范围。

module.exports.logspace = function logspace(a,b,n) {
  return linspace(a,b,n).map(function(x) { return Math.pow(10,x); });
}

我用 C++ 重写了它,它能够支持 > 0 的范围。

您可以执行以下操作

// Create isolethargic binning
    int     T_MIN   = 0;                    //The lower limit i.e. 1.e0
    int     T_MAX   = 8;                    //The uper limit   i.e. 1.e8
    int     ndec    = T_MAX - T_MIN;        //Number of decades
    int     N_BPDEC = 1000;                 //Number of bins per decade
    int     nbins   = (int) ndec*N_BPDEC;   //Total number of bins
    double  step    = (double) ndec / nbins;//The increment 
    double  tbins[nbins+1];                 //The array to store the bins

    for(int i=0; i <= nbins; ++i)
        tbins[i] = (float) pow(10., step * (double) i + T_MIN);