Estoy tratando de convertir un rango de números a otro, manteniendo la relación. Las matemáticas no son mi punto fuerte.
Tengo un archivo de imagen donde los valores de los puntos pueden variar de -16000.00 a 16000.00, aunque el rango típico puede ser mucho menor. Lo que quiero hacer es comprimir estos valores en el rango entero 0-100, donde 0 es el valor del punto más pequeño y 100 es el valor del más grande. Todos los puntos intermedios deben mantener una relación relativa, aunque se pierda algo de precisión. Me gustaría hacer esto en Python, pero incluso un algoritmo general debería ser suficiente. Prefiero un algoritmo en el que se pueda ajustar el rango mínimo / máximo o cualquier rango (es decir, el segundo rango podría ser -50 a 800 en lugar de 0 a 100).
Respuestas:
O un poco más legible:
O si desea proteger para el caso donde el rango anterior es 0 ( OldMin = OldMax ):
Tenga en cuenta que en este caso nos vemos obligados a elegir uno de los posibles valores de rango nuevos de forma arbitraria. Dependiendo del contexto, las opciones razonables podrían ser:
NewMin
( ver muestra )NewMax
o(NewMin + NewMax) / 2
fuente
Esa es una conversión lineal simple.
Entonces, convertir 10000 en la escala de -16000 a 16000 a una nueva escala de 0 a 100 rinde:
fuente
En realidad, hay algunos casos que las respuestas anteriores se romperían. Como valores de entrada incorrectos, rango de entrada incorrecto, rangos de entrada / salida negativos.
fuente
Hay una condición, cuando todos los valores que está verificando son los mismos, donde el código de @ jerryjvl devolvería NaN.
fuente
No desenterré el BNF para esto, pero la documentación de Arduino tenía un gran ejemplo de la función y su desglose. Pude usar esto en Python simplemente agregando un cambio de nombre de definición para reasignar (porque el mapa está integrado) y eliminando los tipos de yeso y llaves (es decir, simplemente elimine todos los 'largos').
Original
Pitón
https://www.arduino.cc/en/reference/map
fuente
En la lista proporcionada por PenguinTD, no entiendo por qué se invierten los rangos, funciona sin tener que revertir los rangos. La conversión de rango lineal se basa en la ecuación lineal
Y=Xm+n
, dondem
yn
se derivan de los rangos dados. En lugar de referirse a los rangos comomin
ymax
, sería mejor referirse a ellos como 1 y 2. Por lo tanto, la fórmula sería:Donde
Y=y1
cuandoX=x1
yY=y2
cuandoX=x2
.x1
,x2
,y1
Yy2
se puede dar ningunapositive
onegative
valor. La definición de la expresión en una macro la hace más útil, luego se puede usar con cualquier nombre de argumento.El
float
reparto garantizaría la división de coma flotante en el caso en que todos los argumentos seaninteger
valores. Dependiendo de la aplicación, puede no ser necesario verificar los rangosx1=x2
yy1==y2
.fuente
float RangeConv(float input, float x1, float x2, float y1, float y2) { return (((input - x1) * (y2 - y1)) / (x2 - x1)) + y1; }
Aquí hay algunas funciones cortas de Python para su facilidad de copiar y pegar, incluida una función para escalar una lista completa.
Que se puede usar así:
En mi caso, quería escalar una curva logarítmica, así:
fuente
Utilicé esta solución en un problema que estaba resolviendo en js, así que pensé en compartir la traducción. Gracias por la explicación y solución.
fuente
Variante C ++
Encontré la solución de PenguinTD útil, así que la porté a C ++ si alguien la necesita:
fuente
Puerto PHP
La solución de PenguinTD me pareció útil, así que la porté a PHP. ¡Ayudar a sí mismo!
fuente
Aquí hay una versión de Javascript que devuelve una función que realiza el cambio de escala para rangos de origen y destino predeterminados, minimizando la cantidad de cómputo que se debe hacer cada vez.
Aquí hay un ejemplo del uso de esta función para escalar 0-1 en -0x80000000, 0x7FFFFFFF
fuente
Propuesta abreviada / simplificada
Wayne
fuente
NewRange/OldRange
aquiYo personalmente uso la clase auxiliar que admite genéricos (compatible con Swift 3)
fuente
Este ejemplo convierte la posición actual de una canción en un rango de ángulo de 20 a 40.
fuente
Lista de comprensión de una solución de línea
Versión más larga
fuente
Versión Java
¡Siempre funciona sin importar lo que alimentes!
Dejé todo expandido para que sea más fácil de seguir para aprender. El redondeo al final, por supuesto, es opcional.
fuente