Ich hätte gerne die Norm eines NumPy-Arrays. Genauer gesagt suche ich nach einer gleichwertigen Version dieser Funktion
def normalize(v):
norm = np.linalg.norm(v)
if norm == 0:
return v
return v / norm
Gibt es so etwas in skearn
oder numpy
?
Diese Funktion funktioniert in einer Situation, in der v
der 0-Vektor ist.
Wenn Sie scikit-learn verwenden, können Sie sklearn.preprocessing.normalize
verwenden:
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
Ich wäre mir einig, dass es schön wäre, wenn eine solche Funktion Bestandteil der mitgelieferten Batterien wäre. Aber so weit ich weiß. Hier ist eine Version für beliebige Achsen mit optimaler Leistung.
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)))
Sie können ord angeben, um die L1-Norm zu erhalten ..__ Um Nullteilung zu vermeiden, verwende ich eps, aber das ist vielleicht nicht so toll.
def normalize(v):
norm=np.linalg.norm(v, ord=1)
if norm==0:
norm=np.finfo(v.dtype).eps
return v/norm
Wenn Sie mehrdimensionale Daten haben und jede Achse auf sich selbst normiert sein soll
def normalize(d):
# d is a (n x dimension) np array
d -= np.min(d, axis=0)
d /= np.ptp(d, axis=0)
return d
Verwendet numpys Spitze zu Spitze Funktion.
Das könnte auch für Sie funktionieren
import numpy as np
normalized_v = v / np.sqrt(np.sum(v**2))
schlägt jedoch fehl, wenn v
die Länge 0 hat.
Es gibt auch die Funktion unit_vector()
, um Vektoren im populären transformations module von Christoph Gohlke zu normalisieren:
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))
Wenn Sie n dimensionale Merkmalsvektoren, die in einem 3D-Tensor gespeichert sind, normalisieren möchten, können Sie auch PyTorch verwenden:
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()
Wenn Sie mit 3D-Vektoren arbeiten, können Sie dies mit dem Werkzeuggürtel vg präzise tun. Es ist eine helle Ebene über Numpy und unterstützt Einzelwerte und gestapelte Vektoren.
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
Ich habe die Bibliothek bei meinem letzten Start erstellt, wo sie durch solche Verwendungszwecke motiviert wurde: einfache Ideen, die in NumPy viel zu ausführlich sind.
Wenn Sie keine äußerste Präzision benötigen, kann Ihre Funktion auf Folgendes reduziert werden:
v_norm = v / (np.linalg.norm(v) + 1e-16)
Sie erwähnten, dass Sci-Kit lernen soll, also möchte ich eine andere Lösung vorstellen.
MinMaxScaler
In sci-kit learn gibt es eine API namens MinMaxScaler
, mit der Sie den Wertebereich nach Ihren Wünschen anpassen können.
Es befasst sich auch mit NaN-Problemen für uns.
NaNs werden als fehlende Werte behandelt: Sie werden in der Anpassung ignoriert und in der Transformation beibehalten. ... siehe Referenz [1]
Der Code ist einfach, einfach eingeben
# 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)
Ohne sklearn
und mit nur numpy
. Definieren Sie einfach eine Funktion:.
Angenommen, die Zeilen sind die Variablen und die Spalten die Stichproben (axis= 1
):
import numpy as np
# Example array
X = np.array([[1,2,3],[4,5,6]])
def stdmtx(X):
means = X.mean(axis =1)
stds = X.std(axis= 1, ddof=1)
X= X - means[:, np.newaxis]
X= X / stds[:, np.newaxis]
return np.nan_to_num(X)
Ausgabe:
X
array([[1, 2, 3],
[4, 5, 6]])
stdmtx(X)
array([[-1., 0., 1.],
[-1., 0., 1.]])