如何在直方图上进行对数合并?
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);
我正在寻找一种以对数方式对某些数据集进行分箱的技术。我们得到的数据的值范围从 _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);