Javascript 将 0 - 1 之间的任何数字归一化的函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39776819/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 22:53:53  来源:igfitidea点击:

Function to normalize any number from 0 - 1

javascriptperformancemathnormalization

提问by Marquizzo

I'm trying to make a function that takes a number and normalizes it from 0 - 1 between its min and max bounds. For example:

我正在尝试创建一个函数,该函数接受一个数字并将其从 0 - 1 的最小值和最大值之间标准化。例如:

If I want to normalize a value of 10 between 5 to 15, I call this:

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

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

val = 10; normalize(val, 5, 15);返回 0.5

normalizing a value 0 between -10 and 5

标准化 -10 到 5 之间的值 0

val = 0; normalize(val, -10, 5);Returns 0.666

val = 0; normalize(val, -10, 5);返回 0.666

This is the function I came up with:

这是我想出的功能:

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

My question is: Is this the most efficient method to normalize a 1-dimensional value? I'm going to be calling this function a few thousand times per frame at 60fps, so I'd like to have it as optimized as possible to reduce the burden of calculation. I've looked for normalization formulas, but all I find are 2- or 3-dimensional solutions.

我的问题是:这是规范化一维值的最有效方法吗?我将以 60fps 每帧调用此函数数千次,因此我希望尽可能优化它以减少计算负担。我一直在寻找归一化公式,但我找到的只是二维或 3 维解决方案。

回答by Nathan Berton

Why not just:

为什么不只是:

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

回答by Nina Scholz

Using Nathan Bertons's answer with a preconfigured function for some values with the same minand maxvalues, you could use this.

Nathan Bertons的答案与一些具有相同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)));

回答by Pedro Diniz

Using Nathan Bertons's answer, you must validate if max-min is equal to zero, otherwise the return will be NaN:

使用Nathan Bertons的答案,您必须验证 max-min 是否等于零,否则返回将是 NaN:

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

and you can use a generalizationto restrict the range of values in the dataset between any arbitrary points a and b using:

并且您可以使用泛化来限制数据集中任意点 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));
}

回答by Andreas Myriounis

I prefer using this formula when I want to normalize a value between two ranges with known min, max values. You can add checks to constrain the input, although this will correctly calculate the difference from the new range if an out-of-range value is given as input.

当我想用已知的最小值、最大值对两个范围之间的值进行归一化时,我更喜欢使用这个公式。您可以添加检查以约束输入,尽管如果将超出范围的值作为输入给出,这将正确计算与新范围的差异。

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

回答by Naim Sulejmani

I Will complete answer of Nina Scholz, you can use underscore library to find minimum and maximum for array and you can use as follow, or create your own (simple methods with simple loop):

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

if you are using nodeJS you need to install underscore with command npm install underscore and use with command var _ = require('underscore/underscore');or you can import the library on html and use on your web

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


回答by Mohit23x

If you want a more dynamic approach, where you can specify the max range, then this can be the solution here, we in this example we are normalizing our data in a range of 0 to 100

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