2010-08-11 7 views
11

Esto debería ser fácil.Escale una lista de números de -1.0 a 1.0

Tengo una lista de números. ¿Cómo escalo los valores de la lista, entre -1.0 y 1.0 para min = -1 y max = 1.0?

+1

Depende. ¿Desea 0 igual a 0 en el resultado final? –

+1

@Alex: Eso ni siquiera es posible si 0 no está en el rango. – relet

+7

¿Qué quiere que suceda en el caso degenerado donde todos los números son iguales? – Hammerite

Respuesta

16

Encontrar el min y la max

entonces para cada escala número x-2 * (x - min)/(max - min) - 1

sólo para comprobar -

  1. escalas min a -1
  2. y max escala a 1

Si es una lista larga precomputar c = 2/(max - min) y escalar con c * x - 1 es una buena idea.

+0

Respaldo la nota sobre precomputación donde sea posible. Su compilador puede no ser lo suficientemente inteligente como para hacer esa optimización automáticamente si usa el formulario de arriba (es probable que no intente conmutar el '2' y el numerador para agrupar las constantes). – bta

+0

Solo para anotar con un ejemplo (usando la entrada que utilicé en mi respuesta para comparar), creo que la lista [-5, -3, -1, 0, 2, 4] se correlacionaría con [-1, -0.55555, -0.11111, 0.11111, 0.55555, 1]. Esto ilustra a qué me refiero cuando pregunto si queremos que 0 siga siendo igual a 0 en los resultados. –

+0

@Alex Sí, pero ¿por qué esperarías que 0 se asignara a 0? – deinst

5

Esta es una normalización firmado

1 - obtener el valor mínimo y máximo en la lista (MINVAL, MaxVal)

2 - convertir cada número con esta Expresiones signedNormal = (((OriginalNumber - Mínimo)/(máximo - mínimo)) * 2,0) - 1,0

deliberadamente hice esta ineficiente con el fin de ser clara - más eficiente sería

double min = myList.GetMinimum(); 
double max = myList.GetMaximum(); 
double signedRangeInverse = 1.0/(max - min); 
for(int i = 0;i < myList.NumberOfItems();i++) 
    myList[i] = (((myList[i] - min) * signedRangeInverse) * 2.0) - 1 

No tiene sentido volver a calcular gama cada vez No tiene sentido dividir gama, mult es más rápido

1

Si desea 0 a siendo igual a 0 en el resultado final:

  1. Halla el número con la magnitud más grande. Esto se asignará a 1 o -1.
  2. Calcula lo que necesitas para multiplicarlo para hacerlo 1 o -1.
  3. Multiplique todos los números de la colección por ese factor.

por ejemplo

[ -5, -3, -1, 0, 2, 4] 

número con una mayor magnitud es -5. Podemos obtener que iguale -1 multiplicando por 0.2 (-1/-5). (Tenga cuidado con dividir por 0 si sus números son todos ceros).

Así que multiplique todos los elementos por 0.2.Esto daría:

[-1, -0.6, -0.2, 0, 0.4, 0.8] 

Aunque nota que

[ -5, -5, -5 ] -> [ -1, -1, -1 ] 

y

[ 5, 5, 5 ] -> [ 1, 1, 1 ] 

y

[ 0, 0, 0 ] -> [ 0, 0, 0 ] 

que pueden o no pueden ser lo que quieres. Gracias a @Hammerite por incitarme sobre eso con su comentario muy útil :)