我试图将一个范围的数字转换为另一个,保持比率。数学不是我的强项。

I have an image file where point values may range from -16000.00 to 16000.00 though the typical range may be much less. What I want to do is compress these values into the integer range 0-100, where 0 is the value of the smallest point, and 100 is the value of the largest. All points in between should keep a relative ratio even though some precision is being lost I'd like to do this in python but even a general algorithm should suffice. I'd prefer an algorithm where the min/max or either range can be adjusted (ie, the second range could be -50 to 800 instead of 0 to 100).


当前回答

捷径/简化方案

 NewRange/OldRange = Handy multiplicand or HM
 Convert OldValue in OldRange to NewValue in NewRange = 
 (OldValue - OldMin x HM) + NewMin

韦恩

其他回答

列出理解一行的解决方案

color_array_new = [int((((x - min(node_sizes)) * 99) / (max(node_sizes) - min(node_sizes))) + 1) for x in node_sizes]

完整版

def colour_specter(waste_amount):
color_array = []
OldRange = max(waste_amount) - min(waste_amount)
NewRange = 99
for number_value in waste_amount:
    NewValue = int((((number_value - min(waste_amount)) * NewRange) / OldRange) + 1)
    color_array.append(NewValue)
print(color_array)
return color_array

捷径/简化方案

 NewRange/OldRange = Handy multiplicand or HM
 Convert OldValue in OldRange to NewValue in NewRange = 
 (OldValue - OldMin x HM) + NewMin

韦恩

增加了KOTLIN版本的数学解释

假设我们有一个介于(OMin, Omax)之间的刻度,我们在这个范围内有一个值X

我们要把它转换成比例(NMin, NMax)

我们知道X,我们需要找到Y,比值必须相等:

 => (Y-NMin)/(NMax-NMin) = (X-OMin)/(OMax-OMin)  
      
 =>  (Y-NMin)/NewRange = (X-OMin)/OldRange 

 =>   Y = ((X-OMin)*NewRange)/oldRange)+NMin  Answer
   

从实用主义的角度来看,我们可以这样写这个问句:

 private fun  convertScale(oldValueToConvert:Int): Float {
       // Old Scale 50-100
       val oldScaleMin = 50
       val oldScaleMax = 100
       val oldScaleRange= (oldScaleMax - oldScaleMin)

       //new Scale 0-1
       val newScaleMin = 0.0f
       val newScaleMax = 1.0f
       val newScaleRange=  (newScaleMax - newScaleMin)
     
       return ((oldValueToConvert - oldScaleMin)* newScaleRange/ oldScaleRange) + newScaleMin
    }

JAVA

/**
     * 
     * @param x
     * @param inMin
     * @param inMax
     * @param outMin
     * @param outMax
     * @return
     */
        private long normalize(long x, long inMin, long inMax, long outMin, long outMax) {
          long outRange = outMax - outMin;
          long inRange  = inMax - inMin;
          return (x - inMin) *outRange / inRange + outMin;
        }

用法:

float brightness = normalize(progress, 0, 10, 0,255);

使用Numpy和interp函数,你可以将你的值从旧范围转换为新范围:

>>> import numpy as np
>>> np.interp(0, [-16000,16000], [0,100])
50.0

你也可以尝试映射一个值列表:

>>> np.interp([-16000,0,12000] ,[-16000,16000], [0,100])
array([ 0. , 50. , 87.5])

有一种情况,当您检查的所有值都相同时,@jerryjvl的代码将返回NaN。

if (OldMin != OldMax && NewMin != NewMax):
    return (((OldValue - OldMin) * (NewMax - NewMin)) / (OldMax - OldMin)) + NewMin
else:
    return (NewMax + NewMin) / 2