Nach der Verarbeitung eines Audio- oder Bild-Arrays muss es innerhalb eines Bereichs normalisiert werden, bevor es in eine Datei zurückgeschrieben werden kann. Das kann so gemacht werden:
# 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)
Gibt es eine weniger ausführliche, praktische Möglichkeit, dies zu tun? matplotlib.colors.Normalize()
scheint nicht verwandt zu sein.
audio /= np.max(np.abs(audio),axis=0)
image *= (255.0/image.max())
Mit /=
und *=
ermöglicht es Ihnen, ein temporäres Zwischenarray zu entfernen, wodurch Speicherplatz gespart wird. Multiplikation ist also billiger als Division
image *= 255.0/image.max() # Uses 1 division and image.size multiplications
ist etwas schneller als
image /= image.max()/255.0 # Uses 1+image.size divisions
Da wir hier grundlegende Numpy-Methoden anwenden, denke ich, dass dies eine möglichst effiziente Lösung für Numpy ist.
In-Place-Vorgänge ändern den d-Typ des Container-Arrays nicht. Da die gewünschten normalisierten Werte Gleitkommazahlen sind, müssen die Arrays audio
und image
Gleitkommazahlen vom Typ d aufweisen, bevor die In-Place-Operationen ausgeführt werden. Wenn sie noch keinen Gleitkomma-D-Typ haben, müssen Sie sie mit astype
konvertieren. Beispielsweise,
image = image.astype('float64')
Wenn das Array sowohl positive als auch negative Daten enthält, würde ich gehen mit:
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
erwähnenswert, auch wenn es sich nicht um die Frage von OP handelt, Standardisierung :
e = (a - np.mean(a)) / np.std(a)
Sie können auch mit sklearn
neu skalieren. Die Vorteile bestehen darin, dass Sie die Standardabweichung zusätzlich zur Mittelwertzentrierung der Daten normalisieren und dies entweder auf der Achse, nach Features oder nach Datensätzen tun können.
from sklearn.preprocessing import scale
X = scale( X, axis=0, with_mean=True, with_std=True, copy=True )
Die Schlüsselwortargumente axis
, with_mean
, with_std
sind selbsterklärend und werden in ihrem Standardzustand angezeigt. Das Argument copy
führt die Operation direkt aus, wenn es auf False
gesetzt ist. Dokumentation hier .
Sie können die "i" -Version (wie in idiv, imul ..) verwenden, und es sieht nicht halb so schlecht aus:
image /= (image.max()/255.0)
Für den anderen Fall können Sie eine Funktion schreiben, um ein n-dimensionales Array nach Spalten zu normalisieren:
def normalize_columns(arr):
rows, cols = arr.shape
for col in xrange(cols):
arr[:,col] /= abs(arr[:,col]).max()
Sie versuchen, die Werte von audio
zwischen -1 und +1 und image
zwischen 0 und 255 von Min-Max zu skalieren.
Mit sklearn.preprocessing.minmax_scale
, sollte Ihr Problem leicht lösen.
z.B.:
audio_scaled = minmax_scale(audio, feature_range=(-1,1))
und
shape = image.shape
image_scaled = minmax_scale(image.ravel(), feature_range=(0,255)).reshape(shape)
Anmerkung : Nicht zu verwechseln mit der Operation, die die Norm (Länge) eines Vektors auf einen bestimmten Wert skaliert (normalerweise) 1), was üblicherweise auch als Normalisierung bezeichnet wird.
Eine einfache Lösung ist die Verwendung der von der Bibliothek sklearn.preprocessing angebotenen Skalierer.
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)
Der Fehler X_rec-X ist Null. Sie können den feature_range an Ihre Bedürfnisse anpassen oder sogar einen Standard-Scaler sk.StandardScaler () verwenden.
Ich habe versucht, this zu folgen, und habe den Fehler erhalten
TypeError: ufunc 'true_divide' output (typecode 'd') could not be coerced to provided output parameter (typecode 'l') according to the casting rule ''same_kind''
Das Array numpy
, das ich zu normalisieren versuchte, war ein Array integer
. Es scheint, als hätten sie das Typumwandeln in Versionen> 1.10
Abgelehnt, und Sie müssen numpy.true_divide()
verwenden, um dies zu beheben.
arr = np.array(img)
arr = np.true_divide(arr,[255.0],out=None)
img
war ein PIL.Image
Objekt.