web-dev-qa-db-fra.com

Comment normaliser un tableau dans NumPy?

Je voudrais avoir la norme d'un tableau NumPy. Plus spécifiquement, je recherche une version équivalente de cette fonction

def normalize(v):
    norm = np.linalg.norm(v)
    if norm == 0: 
       return v
    return v / norm

Y a-t-il quelque chose comme ça dans skearn ou numpy?

Cette fonction fonctionne dans une situation où v est le vecteur 0.

133
Donbeo

Si vous utilisez scikit-learn, vous pouvez utiliser 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
107
ali_m

Je conviendrais que c'était bien si une telle fonction faisait partie des piles incluses. Mais ce n'est pas, pour autant que je sache. Voici une version pour des axes arbitraires, donnant des performances optimales.

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)))
33
Eelco Hoogendoorn

Vous pouvez spécifier ou obtenir la norme L1 ..__ Pour éviter une division nulle, j'utilise eps, mais ce n'est peut-être pas génial.

def normalize(v):
    norm=np.linalg.norm(v, ord=1)
    if norm==0:
        norm=np.finfo(v.dtype).eps
    return v/norm
14
Eduard Feicho

Si vous avez des données multidimensionnelles et que vous voulez que chaque axe soit normalisé sur lui-même:

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

Utilise numpys crête à crête fonction.

6
Jaden Travnik

Cela pourrait aussi fonctionner pour vous

import numpy as np
normalized_v = v / np.sqrt(np.sum(v**2))

mais échoue lorsque v a la longueur 0.

5
mrk

Il existe également la fonction unit_vector() pour normaliser les vecteurs dans le populaire module transformations de Christoph Gohlke:

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))
2
Joe

Si vous voulez normaliser des vecteurs d'entités à n dimensions stockés dans un tenseur 3D, vous pouvez également utiliser 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()
1
max0r

Si vous travaillez avec des vecteurs 3D, vous pouvez le faire de manière concise en utilisant toolbelt vg . C'est une couche légère au-dessus de numpy et elle supporte les valeurs uniques et les vecteurs empilés.

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

J'ai créé la bibliothèque lors de mon dernier démarrage, où elle était motivée par des utilisations telles que celle-ci: des idées simples et trop verbeuses dans NumPy.

1
paulmelnikow

Si vous n'avez pas besoin de la plus grande précision, votre fonction peut être réduite à:

v_norm = v / (np.linalg.norm(v) + 1e-16)
1
sergio verduzco

Vous avez mentionné sci-kit learn, alors je veux partager une autre solution.

sci-kit learn MinMaxScaler

Dans sci-kit learn, il existe une API appelée MinMaxScaler qui permet de personnaliser la plage de valeurs à votre guise.

Il traite également des problèmes NaN pour nous.

Les NaN sont traités comme des valeurs manquantes: ignorés dans l'ajustement et conservés dans la transformation. ... voir la référence [1]

Échantillon de code

Le code est simple, il suffit de taper

# 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)
0
WY Hsu

Sans sklearn et en utilisant seulement numpy. Il suffit de définir une fonction:.

En supposant que les lignes sont les variables et les colonnes les échantillons (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)

sortie:

X
array([[1, 2, 3],
       [4, 5, 6]])

stdmtx(X)
array([[-1.,  0.,  1.],
       [-1.,  0.,  1.]])

0
serafeim