Po wykonaniu pewnego przetwarzania na tablicy audio lub obrazu, należy go znormalizować w pewnym zakresie, zanim będzie można go zapisać z powrotem do pliku. Można to zrobić w następujący sposób:
# 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)
Czy istnieje mniej szczegółowy, wygodny sposób na zrobienie tego? matplotlib.colors.Normalize()
nie wydaje się być powiązany.
Jeśli tablica zawiera zarówno dane dodatnie, jak i ujemne, zastosowałbym:
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
Jeśli tablica zawiera
nan
, jednym rozwiązaniem może być po prostu usunięcie ich jako:def nan_ptp(a): return np.ptp(a[np.isfinite(a)]) b = (a - np.nanmin(a))/nan_ptp(a)
Jednak w zależności od kontekstu możesz chcieć traktować
nan
inaczej. Np. Interpoluj wartość, zastępując ją np. 0 lub zgłoś błąd.Na koniec warto wspomnieć, nawet jeśli nie jest to pytanie OP, standaryzacja :
źródło
scipy.stats.zscore
.f = a / np.max(np.abs(a))
... chyba, że cała tablica zawiera wszystkie zera (unikaj DivideByZero).numpy.ptp()
zwraca 0, jeśli jest to zakres, alenan
jeśli istnieje takinan
w tablicy. Jeśli jednak zakres wynosi 0, normalizacja nie jest zdefiniowana. To rodzi błąd, ponieważ próbujemy podzielić przez 0.Możesz również przeskalować za pomocą
sklearn
. Zaletą jest to, że oprócz wyśrodkowania danych można dostosować normalizację odchylenia standardowego i można to zrobić na dowolnej osi, według cech lub rekordów.from sklearn.preprocessing import scale X = scale( X, axis=0, with_mean=True, with_std=True, copy=True )
Argumenty słów kluczowych
axis
,with_mean
,with_std
są wymowne i są pokazane w ich domyślnego stanu. Argumentcopy
wykonuje operację w miejscu, jeśli jest ustawiony naFalse
. Dokumentacja tutaj .źródło
Możesz użyć wersji „i” (jak w idiv, imul ..) i nie wygląda to tak źle:
image /= (image.max()/255.0)
W drugim przypadku możesz napisać funkcję normalizującą n-wymiarową tablicę za pomocą kolumn:
def normalize_columns(arr): rows, cols = arr.shape for col in xrange(cols): arr[:,col] /= abs(arr[:,col]).max()
źródło
/=
zamiast= .. / ..
Próbujesz skalować wartości min-max z zakresu
audio
od -1 do +1 orazimage
od 0 do 255.Używanie
sklearn.preprocessing.minmax_scale
powinno łatwo rozwiązać twój problem.na przykład:
audio_scaled = minmax_scale(audio, feature_range=(-1,1))
i
shape = image.shape image_scaled = minmax_scale(image.ravel(), feature_range=(0,255)).reshape(shape)
Uwaga : Nie należy mylić z operacją, która skaluje normę (długość) wektora do określonej wartości (zwykle 1), co jest również powszechnie określane jako normalizacja.
źródło
Prostym rozwiązaniem jest użycie skalerów oferowanych przez bibliotekę 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)
Błąd X_rec-X będzie wynosił zero. Możesz dostosować feature_range do swoich potrzeb, a nawet użyć standardowego skalera sk.StandardScaler ()
źródło
Próbowałem postępować zgodnie z tym i otrzymałem błąd
TypeError: ufunc 'true_divide' output (typecode 'd') could not be coerced to provided output parameter (typecode 'l') according to the casting rule ''same_kind''
numpy
Tablica starałem normalizować byłinteger
tablicą. Wygląda na to, że przestarzałe rzutowanie typów w wersjach>1.10
i musisz użyć,numpy.true_divide()
aby rozwiązać ten problem.arr = np.array(img) arr = np.true_divide(arr,[255.0],out=None)
img
byłPIL.Image
przedmiotem.źródło