将 0 - 1 中的任何数字归一化的函数

Function to normalize any number from 0 - 1

我正在尝试制作一个函数,它接受一个数字并将其从 0 - 1 归一化到其最小和最大范围之间。例如:

如果我想将 10 的值标准化为 5 到 15 之间,我称之为:

val = 10; normalize(val, 5, 15); Returns 0.5

在 -10 和 5 之间标准化一个值 0

val = 0; normalize(val, -10, 5); Returns 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 的速度每帧调用此函数数千次,因此我希望尽可能优化它以减少计算负担。我找过归一化公式,但我找到的都是 2 维或 3 维解。

为什么不只是:

function(val, max, min) { return (val - min) / (max - min); }

的答案与具有相同 minmax 值的某些值的预配置函数一起使用,您可以使用它。

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)));

使用的答案,你必须验证max-min是否等于0,否则return将为NaN:

function (val, max, min) { 
    if(max - min === 0) return 1; // or 0, it's up to you
    return (val - min) / (max - min); 
}

并且您可以使用 generalization 来限制数据集中任意点 a 和 b 之间的值范围:

function (val, max, min) {
    if(max - min === 0) return a; // or b, it's up to you
    return a + (((val - min) * (b-a)) / (max - min));
}

我将完成 Nina Scholz 的回答,您可以使用下划线库来查找数组的最小值和最大值,您可以按如下方式使用,或者创建您自己的(简单循环的简单方法):

如果您使用的是 nodeJS,则需要使用命令 npm install underscore 安装 underscore 并使用命令 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));


当我想对两个具有已知最小值和最大值的范围之间的值进行归一化时,我更喜欢使用此公式。您可以添加检查以限制输入,但如果输入的值超出范围,这将正确计算与新范围的差异。

/**
 * 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>

如果你想要一个更动态的方法,你可以在其中指定最大范围,那么这就是这里的解决方案,我们在这个例子中我们在 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))

max-min限制

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个 ]