¿Cómo normalizar una matriz NumPy dentro de un rango determinado?

Resuelto endolith asked hace 15 años • 8 respuestas

Después de realizar algún procesamiento en una matriz de audio o imagen, es necesario normalizarla dentro de un rango antes de poder volver a escribirla en un archivo. Esto se puede hacer así:

# Normalize audio channels to between -1.0 and +1.0
audio[:,0] = audio[:,0]/abs(audio[:,0]).max()
audio[:,1] = audio[:,1]/abs(audio[:,1]).max()

# Normalize image to between 0 and 255
image = image/(image.max()/255.0)

¿Existe una forma funcional menos detallada y conveniente de hacer esto? matplotlib.colors.Normalize()no parece estar relacionado.

endolith avatar Nov 15 '09 00:11 endolith
Aceptado
# Normalize audio channels to between -1.0 and +1.0
audio /= np.max(np.abs(audio),axis=0)
# Normalize image to between 0 and 255
image *= (255.0/image.max())

Usar /=y *=le permite eliminar una matriz temporal intermedia, ahorrando así algo de memoria. La multiplicación es menos costosa que la división, por lo que

image *= 255.0/image.max()    # Uses 1 division and image.size multiplications

es marginalmente más rápido que

image /= image.max()/255.0    # Uses 1+image.size divisions

Dado que aquí utilizamos métodos básicos de numpy, creo que esta es una solución lo más eficiente posible en numpy.


Las operaciones in situ no cambian el tipo de matriz de contenedores. Dado que los valores normalizados deseados son flotantes, las matrices audioy imagedeben tener un tipo de punto flotante antes de que se realicen las operaciones in situ. Si aún no son de tipo punto flotante, deberá convertirlos usando astype. Por ejemplo,

image = image.astype('float64')
unutbu avatar Nov 14 '2009 18:11 unutbu

Si la matriz contiene datos tanto positivos como negativos, elegiría:

import numpy as np

a = np.random.rand(3,2)

# Normalised [0,1]
b = (a - np.min(a))/np.ptp(a)

# Normalised [0,255] as integer: don't forget the parenthesis before astype(int)
c = (255*(a - np.min(a))/np.ptp(a)).astype(int)        

# Normalised [-1,1]
d = 2.*(a - np.min(a))/np.ptp(a)-1

Si la matriz contiene nan, una solución podría ser simplemente eliminarlos como:

def nan_ptp(a):
    return np.ptp(a[np.isfinite(a)])

b = (a - np.nanmin(a))/nan_ptp(a)

Sin embargo, dependiendo del contexto es posible que desee tratarlo nande manera diferente. Por ejemplo, interpolar el valor, reemplazándolo con, por ejemplo, 0, o generar un error.

Finalmente, vale la pena mencionar, incluso si no es una pregunta de OP, la estandarización :

e = (a - np.mean(a)) / np.std(a)
user2821 avatar Jul 08 '2017 07:07 user2821