¿Cómo normalizar una Colección de la matriz dentro de un cierto rango?
-
20-09-2019 - |
Pregunta
Después de hacer algunas tareas de procesamiento de audio o la imagen de la matriz, debe ser normalizada dentro de un rango antes de que pueda ser escrito 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)
Hay un menos detallado, función de conveniencia manera de hacer esto? matplotlib.colors.Normalize()
no parecen estar relacionados.
Solución
audio /= np.max(np.abs(audio),axis=0)
image *= (255.0/image.max())
El uso de /=
y *=
le permite eliminar una serie temporal intermedio, lo que ahorra 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
Ya que estamos usando métodos básicos numpy aquí, creo que esto se trata de una solución tan eficiente en numpy como puede ser.
En lugar operaciones no cambian la dtype de la matriz recipiente. Dado que los valores normalizados deseados son flotadores, las matrices audio
y image
necesita tener dtype punto de punto flotante antes se llevan a cabo las operaciones en el lugar.
Si no están ya de punto flotante dtype, que necesita para convertirlos utilizando astype
. Por ejemplo,
image = image.astype('float64')
Otros consejos
Si la matriz contiene tanto los datos positivos y negativos, me gustaría ir con:
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
c = 255*(a - np.min(a))/np.ptp(a).astype(int)
# Normalised [-1,1]
d = 2.*(a - np.min(a))/np.ptp(a)-1
También, vale la pena mencionar, incluso si no es la pregunta de OP, estandarización :
e = (a - np.mean(a)) / np.std(a)
También puede cambiar la escala usando sklearn
. Las ventajas son que se puede ajustar a normalizar la desviación estándar, además de significar-centrado de los datos, y que usted puede hacer esto en cualquiera de los ejes, por sus características o por los registros.
from sklearn.preprocessing import scale
X = scale( X, axis=0, with_mean=True, with_std=True, copy=True )
La argumentos clave axis
, with_mean
, with_std
son explica por sí mismo, y se muestran en su estado predeterminado. El argumento copy
realiza la operación en el lugar si se establece a False
. aquí .
Puede utilizar la "i" (como en idiv, imul ..) versión, y no se ve nada mal:
image /= (image.max()/255.0)
En el otro caso, se puede escribir una función para normalizar una matriz n-dimensional mediante columnas:
def normalize_columns(arr):
rows, cols = arr.shape
for col in xrange(cols):
arr[:,col] /= abs(arr[:,col]).max()
Una solución simple está utilizando los escaladores que ofrece la biblioteca sklearn.preprocessing.
scaler = sk.MinMaxScaler(feature_range=(0, 250))
scaler = scaler.fit(X)
X_scaled = scaler.transform(X)
# Checking reconstruction
X_rec = scaler.inverse_transform(X_scaled)
El error X_rec-X será cero. Se puede ajustar el feature_range para sus necesidades, o incluso el uso de un escalador sk.StandardScaler standart ()
Usted está tratando de min-max de la escala de los valores de audio
entre -1 y +1 y image
entre 0 y 255.
El uso de sklearn.preprocessing.minmax_scale
, debe resolver fácilmente el problema.
por ejemplo:
audio_scaled = minmax_scale(audio, feature_range=(-1,1))
y
shape = image.shape
image_scaled = minmax_scale(image.ravel(), feature_range=(0,255)).reshape(shape)
nota:No se debe confundir con la operación de que las escalas de la norma (longitud) de un vector a un valor determinado (generalmente 1), que es también comúnmente se conoce como normalización.
este , y tengo el error
TypeError: ufunc 'true_divide' output (typecode 'd') could not be coerced to provided output parameter (typecode 'l') according to the casting rule ''same_kind''
La matriz numpy
yo estaba tratando de normalizar era una matriz integer
. Parece que la conversión de tipos en desuso en las versiones> 1.10
, y usted tiene que utilizar numpy.true_divide()
para resolver eso.
arr = np.array(img)
arr = np.true_divide(arr,[255.0],out=None)
img
era un objeto PIL.Image
.