Étant donné un tableau 3 fois 3 numpy
a = numpy.arange(0,27,3).reshape(3,3)
# array([[ 0, 3, 6],
# [ 9, 12, 15],
# [18, 21, 24]])
Pour normaliser les lignes du tableau à 2 dimensions auquel j'ai pensé
row_sums = a.sum(axis=1) # array([ 9, 36, 63])
new_matrix = numpy.zeros((3,3))
for i, (row, row_sum) in enumerate(Zip(a, row_sums)):
new_matrix[i,:] = row / row_sum
Il doit y avoir un meilleur moyen, n'est-ce pas?
Peut-être pour clarifier: par normalisation, je veux dire, la somme des entrées par ligne doit être une. Mais je pense que cela sera clair pour la plupart des gens.
La radiodiffusion est vraiment bonne pour cela:
row_sums = a.sum(axis=1)
new_matrix = a / row_sums[:, numpy.newaxis]
row_sums[:, numpy.newaxis]
remodèle les sommes de row_de somme de (3,)
à (3, 1)
. Lorsque vous faites a / b
, a
et b
sont diffusés l'un contre l'autre.
Vous pouvez en savoir plus sur broadcasthere ou même mieux here .
Scikit-learn a une fonction de normalisation qui vous permet d’appliquer diverses normalisations. Le "faire la somme à 1" est la norme L1, et pour prendre cela faire:
from sklearn.preprocessing import normalize
matrix = numpy.arange(0,27,3).reshape(3,3).astype(numpy.float64)
#array([[ 0., 3., 6.],
# [ 9., 12., 15.],
# [ 18., 21., 24.]])
normed_matrix = normalize(matrix, axis=1, norm='l1')
#[[ 0. 0.33333333 0.66666667]
#[ 0.25 0.33333333 0.41666667]
#[ 0.28571429 0.33333333 0.38095238]]
Maintenant, vos lignes totaliseront 1.
Je pense que cela devrait fonctionner,
a = numpy.arange(0,27.,3).reshape(3,3)
a /= a.sum(axis=1)[:,numpy.newaxis]
Si vous essayez de normaliser chaque ligne de telle sorte que sa magnitude soit égale à un (c'est-à-dire que la longueur unitaire d'une ligne est égale à un ou que la somme du carré de chaque élément d'une ligne correspond à un)
import numpy as np
a = np.arange(0,27,3).reshape(3,3)
result = a / np.linalg.norm(a, axis=-1)[:, np.newaxis]
# array([[ 0. , 0.4472136 , 0.89442719],
# [ 0.42426407, 0.56568542, 0.70710678],
# [ 0.49153915, 0.57346234, 0.65538554]])
Vérification:
np.sum( result**2, axis=-1 )
# array([ 1., 1., 1.])
il semble que cela fonctionne aussi
def normalizeRows(M):
row_sums = M.sum(axis=1)
return M / row_sums
Ou en utilisant la fonction lambda, comme
>>> vec = np.arange(0,27,3).reshape(3,3)
>>> import numpy as np
>>> norm_vec = map(lambda row: row/np.linalg.norm(row), vec)
chaque vecteur de vec aura une norme d'unité.
Je pense que vous pouvez normaliser la somme des éléments de ligne à 1 par ceci: new_matrix = a / a.sum(axis=1, keepdims=1)
. Et la normalisation des colonnes peut être effectuée avec new_matrix = a / a.sum(axis=0, keepdims=1)
. J'espère que ça peut marcher.
Vous pouvez également utiliser la transposition matricielle:
(a.T / row_sums).T