Как нормализовать массив NumPy в пределах определенного диапазона?
после выполнения некоторой обработки на массиве аудио или изображений, он должен быть нормализован в пределах диапазона, прежде чем он может быть записан обратно в файл. Это можно сделать так:
# 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)
есть ли менее подробный, удобный способ сделать это? matplotlib.colors.Normalize() не похоже, что это связано.
6 ответов:
audio /= np.max(np.abs(audio),axis=0) image *= (255.0/image.max())используя
/=и*=позволяет устранить промежуточное временный массив, тем самым экономя память. Умножение стоит дешевле, чем деление, так чтоimage *= 255.0/image.max() # Uses 1 division and image.size multiplicationsнамного быстрее, чем
image /= image.max()/255.0 # Uses 1+image.size divisionsтак как мы используем основные методы numpy здесь, я думаю, что это примерно такое же эффективное решение в numpy, как может быть.
вы также можете масштабировать с помощью
sklearn. Преимущества заключаются в том, что вы можете настроить нормализацию стандартного отклонения в дополнение к среднему центрированию данных и что вы можете сделать это на любой оси, по объектам или по записям.from sklearn.preprocessing import scale X = scale( X, axis=0, with_mean=True, with_std=True, copy=True )аргументы ключевого слова
axis,with_mean,with_stdявляются самоочевидными и отображаются в состоянии по умолчанию. Аргументcopyвыполняет операцию на месте, если это значениеFalse. Документация здесь.
Если массив содержит как положительные, так и отрицательные данные, я бы пошел с:
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кроме того, стоит упомянуть, даже если это не вопрос ОП,стандартизация:
e = (a - np.mean(a)) / np.std(a)
вы можете использовать "я" (как в idiv, imul..) версия, и это не выглядит так уж плохо:
image /= (image.max()/255.0)в другом случае вы можете написать функцию для нормализации n-мерного массива по столбцам:
def normalize_columns(arr): rows, cols = arr.shape for col in xrange(cols): arr[:,col] /= abs(arr[:,col]).max()
простое решение заключается в использовании скалеров, предлагаемых sklearn.библиотека предварительной обработки.
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)ошибка X_rec-X будет равна нулю. Вы можете настроить feature_range для ваших нужд, или даже использовать стандартный скалер sk.StandardScaler ()
Я пытался следовать этой, и получил ошибку
TypeError: ufunc 'true_divide' output (typecode 'd') could not be coerced to provided output parameter (typecode 'l') according to the casting rule ''same_kind''The
numpyмассив, который я пытался нормализовать, былintegerмассив. Кажется, они устарели литье типов в версиях >1.10, и вы должны использоватьnumpy.true_divide()чтобы решить эту проблему.arr = np.array(img) arr = np.true_divide(arr,[255.0],out=None)
imgбыл
Comments