我正在尝试创建一个函数,它接受一个数字并将其从最小和最大边界之间的0 - 1标准化。例如:
如果我想在10到15之间将值10标准化,我称之为:
val = 10; normalize(val, 5, 15);
返回0.5
将值0标准化为-10到5之间
val = 0; normalize(val, -10, 5);
返回0.666
这是我提出的功能:
function normalize(val, min, max){
// Shift to positive to avoid issues when crossing the 0 line
if(min < 0){
max += 0 - min;
val += 0 - min;
min = 0;
}
// Shift values from 0 - max
val = val - min;
max = max - min;
return Math.max(0, Math.min(1, val / max));
}
我的问题是:这是规范化一维值的最有效方法吗?我将以每帧60fps的速度调用此函数几千次,因此我希望尽可能优化它以减少计算负担。我已经找到了规范化公式,但我找到的只是二维或三维解。
答案 0 :(得分:32)
为什么不呢:
function(val, max, min) { return (val - min) / (max - min); }
答案 1 :(得分:8)
对于具有相同min
和max
值的某些值,使用Nathan Bertons的答案和预先配置的函数,您可以使用此功能。
function normalize(min, max) {
var delta = max - min;
return function (val) {
return (val - min) / delta;
};
}
console.log([5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15].map(normalize(5, 15)));
答案 2 :(得分:3)
使用Nathan Bertons的答案,您必须验证max-min是否等于零,否则返回值为NaN:
.margin-bottom-five{
margin-bottom: 5;
}
,您可以使用generalization将数据集中值的范围限制在任意点a和b之间,方法是:
function (val, max, min) {
if(max - min === 0) return 1 // or 0, it's up to you
return (val - min) / (max - min);
}
答案 3 :(得分:0)
当我想用已知的最小,最大值对两个范围之间的值进行归一化时,我更喜欢使用此公式。您可以添加检查来约束输入,尽管如果输入的值超出范围,这将正确计算与新范围的差。
/**
* Normalizes a value from one range (current) to another (new).
*
* @param { Number } val //the current value (part of the current range).
* @param { Number } minVal //the min value of the current value range.
* @param { Number } maxVal //the max value of the current value range.
* @param { Number } newMin //the min value of the new value range.
* @param { Number } newMax //the max value of the new value range.
*
* @returns { Number } the normalized value.
*/
const normalizeBetweenTwoRanges = (val, minVal, maxVal, newMin, newMax) => {
return newMin + (val - minVal) * (newMax - newMin) / (maxVal - minVal);
};
const e = document.getElementById('result');
e.innerHTML = normalizeBetweenTwoRanges(10, 5, 15, 0, 1);
<span id="result"></span>
答案 4 :(得分:0)
如果您想要一种更动态的方法,可以在其中指定最大范围,那么这可以作为解决方案,在此示例中,我们将数据标准化为0到100
let a = [500, 2000, 3000, 10000];
function normalize(data, arr_max, arr_min, newMax){
return data.map(d => {
return newMax * ((d - arr_min)/(arr_max - arr_min))
})
}
console.log(normalize(a, 10000, 500, 100))
答案 5 :(得分:0)
有最大-最小限制
function normalize(min, max) {
const delta = max - min;
return val => ( (val < min? min: (val > max? max : val)) - min ) / delta;
}
console.log([-2,3,5, 6, 7, 8, 9, 10,11,23].map(normalize(0, 10)));
// [
输出:[0, 0.3, 0.5, 0.6, 0.7, 0.8, 0.9, 1、 1、 1 ]
答案 6 :(得分:-1)
我将完整回答Nina Scholz的答案,您可以使用下划线库查找数组的最小值和最大值,并且可以按以下方式使用,或创建自己的(带有简单循环的简单方法):
如果使用的是nodeJS,则需要使用命令npm安装下划线并安装下划线并与命令一起使用
var _ = require('underscore/underscore');
或者您可以导入html上的库并在网络上使用
function min(arr) {
if (!arr.length) return null;
var minValue = arr[0];
for (var item of arr) {
if (item maxValue) maxValue = item;
}
return maxValue;
}
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9];
function normalize(min, max) {
var delta = max - min;
return function (val) {
return (val - min) / delta;
};
}
function normalizeArray(array) {
var minValue = min(array); //if you use underscore _.min(array)
var maxValue = max(array);//if you use underscore _.max(array)
return array.map(normalize(minValue, maxValue));
}
console.log(normalizeArray(array));