python - array - ¿Cómo normalizar una matriz NumPy dentro de un cierto rango?
numpy python (6)
Intenté seguir this y obtuve 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
que intentaba normalizar era una matriz integer
. Parece que desaprobaron la conversión de tipos en las versiones> 1.10
, y tienes que usar 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
.
Después de realizar un procesamiento en una matriz de audio o de imagen, debe normalizarse dentro de un rango antes de poder volver a escribirse 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 una manera menos detallada y conveniente de hacer esto? matplotlib.colors.Normalize()
no parece estar relacionado.
Puede usar la versión "i" (como en idiv, imul ..) y no se ve tan mal:
image /= (image.max()/255.0)
Para el otro caso, puede escribir una función para normalizar una matriz n-dimensional por columnas:
def normalize_columns(arr):
rows, cols = arr.shape
for col in xrange(cols):
arr[:,col] /= abs(arr[:,col]).max()
Si la matriz contiene datos positivos y negativos, yo 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
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, la standardization :
e = (a - np.mean(a)) / np.std(a)
También puede sklearn
escala usando sklearn
. Las ventajas son que puede ajustar la normalización de la desviación estándar, además de centrar los datos, y que puede hacerlo en cualquier eje, por características o por registros.
from sklearn.preprocessing import scale
X = scale( X, axis=0, with_mean=True, with_std=True, copy=True )
Los axis
palabras clave axis
, with_mean
, with_std
se explican por sí mismos y se muestran en su estado predeterminado. La copy
argumento realiza la operación in situ si está establecida en False
. Documentación here .
Una solución simple es usar los escaladores ofrecidos por 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. Puede ajustar el rango de características para sus necesidades, o incluso usar un escalador estándar sk.StandardScaler ()
audio /= np.max(np.abs(audio),axis=0)
image *= (255.0/image.max())
Usar /=
y *=
permite eliminar una matriz temporal intermedia, ahorrando algo de memoria. La multiplicación es menos costosa que la división, por lo
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 estamos usando métodos numpy básicos aquí, creo que esta es una solución tan eficiente en numpy como puede ser.