Я хотел бы получить норму одного массива NumPy. Более конкретно, я ищу эквивалентную версию этой функции
def normalize(v):
norm = np.linalg.norm(v)
if norm == 0:
return v
return v / norm
Есть ли что-то подобное в skearn
или numpy
?
Эта функция работает в ситуации, когда v
- вектор 0.
Если вы используете scikit-learn, вы можете использовать sklearn.preprocessing.normalize
:
import numpy as np
from sklearn.preprocessing import normalize
x = np.random.rand(1000)*10
norm1 = x / np.linalg.norm(x)
norm2 = normalize(x[:,np.newaxis], axis=0).ravel()
print np.all(norm1 == norm2)
# True
Я согласен, что было бы неплохо, если бы такая функция была в комплекте с батарейками. Но это не так, насколько я знаю. Вот версия для произвольных осей, дающая оптимальную производительность.
import numpy as np
def normalized(a, axis=-1, order=2):
l2 = np.atleast_1d(np.linalg.norm(a, order, axis))
l2[l2==0] = 1
return a / np.expand_dims(l2, axis)
A = np.random.randn(3,3,3)
print(normalized(A,0))
print(normalized(A,1))
print(normalized(A,2))
print(normalized(np.arange(3)[:,None]))
print(normalized(np.arange(3)))
Вы можете указать ord, чтобы получить норму L1. Чтобы избежать деления на ноль, я использую eps, но это, возможно, не очень хорошо.
def normalize(v):
norm=np.linalg.norm(v, ord=1)
if norm==0:
norm=np.finfo(v.dtype).eps
return v/norm
Если у вас есть многомерные данные и хотите, чтобы каждая ось нормированная на максимум или его сумма:
def normalize(_d, to_sum=True, copy=True):
# d is a (n x dimension) np array
d = _d if not copy else np.copy(_d)
d -= np.min(d, axis=0)
d /= (np.sum(d, axis=0) if to_sum else np.ptp(d, axis=0))
return d
Использует numpys пик-пик функция.
a = np.random.random((5, 3))
b = normalize(a, copy=False)
b.sum(axis=0) # array([1., 1., 1.]), the rows sum to 1
c = normalize(a, to_sum=False, copy=False)
c.max(axis=0) # array([1., 1., 1.]), the max of each row is 1
Это может также работать для вас
import numpy as np
normalized_v = v / np.sqrt(np.sum(v**2))
но не когда " в " Имеет длину 0.
Также unit_vector функции ()
, чтобы нормализовать векторы в популярном трансформации модуль Кристоф голк:
import transformations as trafo
import numpy as np
data = np.array([[1.0, 1.0, 0.0],
[1.0, 1.0, 1.0],
[1.0, 2.0, 3.0]])
print(trafo.unit_vector(data, axis=1))
Если вы хотите нормализовать мерного признакового Н храниться в 3D тензора, вы также можете использовать PyTorch:
import numpy as np
from torch import FloatTensor
from torch.nn.functional import normalize
vecs = np.random.rand(3, 16, 16, 16)
norm_vecs = normalize(FloatTensor(vecs), dim=0, eps=1e-16).numpy()
Если вы'работаете с 3D-векторов, вы можете сделать это сжато с помощью угловатого ВГ. Это'С легким слоем поверх NumPy и поддерживает отдельные значения и складывают векторы.
import numpy as np
import vg
x = np.random.rand(1000)*10
norm1 = x / np.linalg.norm(x)
norm2 = vg.normalize(x)
print np.all(norm1 == norm2)
# True
Я создал библиотеку в мой последний стартап, где он был мотивирован использует, как это: простые идеи, которые являются слишком многословен в пакете numpy.
Вы упомянули научно-Kit узнать, поэтому я хочу поделиться другим решением.
В научно-Kit узнать, есть API под названием MinMaxScaler
, который может настроить диапазон значений, как вам нравится.
Он также бороться с НАН для нас вопросов.
Нанс рассматриваются как отсутствующие значения: учитываются в форме, и поддерживать В трансформации. ... см. ссылку [1]
Код простой, просто введите
# Let's say X_train is your input dataframe
from sklearn.preprocessing import MinMaxScaler
# call MinMaxScaler object
min_max_scaler = MinMaxScaler()
# feed in a numpy array
X_train_norm = min_max_scaler.fit_transform(X_train.values)
# wrap it up if you need a dataframe
df = pd.DataFrame(X_train_norm)
Если вы Don'т нужна предельная точность, ваша функция может быть сведена к:
v_norm = v / (np.linalg.norm(v) + 1e-16)
Без sklearn и используя только библиотеки numpy`. Просто определите функцию:.
При условии, что строк переменных и столбцы образцы (оси= 1
):
`` импорт включает в себя как НП
Пример # массив Х = НП.массив([[1,2,3],[4,5,6]])
деф stdmtx(х): значит = означает Х.(оси =1) ЗППП = X. В СТД(оси= 1, ddof=1) Х= Х - значит[:, НП.newaxis] Х= Х / ЗППП[:, НП.newaxis] возвратить НП.nan_to_num(х)
``
выход:
`` Х массив([[1, 2, 3], [4, 5, 6]])
stdmtx(х) массив([[-1., 0., 1.], [-1., 0., 1.]])
``
Если вы работаете с многомерного массива следующая быстрое решение возможно.
Скажем, у нас есть 2Д массив, который мы хотим нормализовать на последней оси, в то время как некоторые строки имеют нулевую норму.
``питон импорт включает в себя как НП Арр = НП.массив([ [1, 2, 3], [0, 0, 0], [5, 6, 7] ], dtype=НП.поплавок)
длины = НП.linalg.норма(Арр оси=-1) печати(длин) # [ 3.74165739 0. 10.48808848] Арр[длин > 0] = ОБР[длин > 0] / длина[длин > 0][:, НП.newaxis] печати(аранж)
``