python - rescale a value between two numerical ranges

9.8k Views Asked by At

I am trying to convert a value, comprised in the range of two integers, to another integer comprised in an other given range. I want the output value to be the corresponding value of my input integer (respecting the proportions). To be more clear, here is an example of the problem I'd like to solve:

  • Suppose I have three integers, let's say 10, 28 and 13, that are comprised in the range (10, 28). 10 is the minimum possible value, 28 the maximum possible value.
  • I want, as output, integers converted to the 'corresponding' number in the range (5, 20). In this precise example, 10 would be converted to 5, 28 to 20, and 13 to a value between 5 and 20, rescaled to keep the proportions intacts. Afterwards, this value is converted to integer.

How is it possible to achieve such 'rescaling' in python ? I tried the usual calculation (value/max of first range)*max of second range but it gives wrong values except in rare cases.

At first I had problems with the division with intin python, but after correcting this, I still have wrong values. For instance, using the values given in the example, int((float(10)/28)*20) will give me 7 as result, where it should return 5 because it's the minimum possible value in the first range.

I feel like it is a bit obvious (in terms of logic and math) and I am missing something.

1

There are 1 best solutions below

1
On BEST ANSWER

If you are getting wrong results, you are likely using Python2 - where a division always yield an integer - (and therefore you will get lots of rounding errors and "zeros" when it comes to scaling factors.

Python3 corrected this so that divisions return floats - in Python2 the workaround is either to put a from __future__ import division on the first line of your code (preferred), or to explicitly convert at least one of the division operands to float - on every division.

from __future__ import division

def renormalize(n, range1, range2):
    delta1 = range1[1] - range1[0]
    delta2 = range2[1] - range2[0]
    return (delta2 * (n - range1[0]) / delta1) + range2[0]