3 x 3 numpy配列が与えられた場合
a = numpy.arange(0,27,3).reshape(3,3)
# array([[ 0, 3, 6],
# [ 9, 12, 15],
# [18, 21, 24]])
私が考えた2次元配列の行を正規化するには
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
もっと良い方法があるはずですよね?
おそらく明確にするために:正規化することで、行ごとのエントリの合計は1でなければなりません。しかし、それはほとんどの人にとって明らかだと思います。
Scikit-learnには、さまざまな正規化を適用できる正規化機能があります。 「合計を1にする」はL1の標準であり、それを行うには:
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]]
これで、行の合計は1になります。
これでうまくいくと思う
a = numpy.arange(0,27.,3).reshape(3,3)
a /= a.sum(axis=1)[:,numpy.newaxis]
大きさが1になるように各行を正規化しようとしている場合(つまり、行の単位長が1であるか、行内の各要素の平方和が1である場合):
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]])
検証中:
np.sum( result**2, axis=-1 )
# array([ 1., 1., 1.])
これも機能するようです
def normalizeRows(M):
row_sums = M.sum(axis=1)
return M / row_sums
または、ラムダ関数を使用して、
>>> vec = np.arange(0,27,3).reshape(3,3)
>>> import numpy as np
>>> norm_vec = map(lambda row: row/np.linalg.norm(row), vec)
vecの各ベクトルには単位ノルムがあります。
これにより、行要素の合計を1に正規化できると思います:new_matrix = a / a.sum(axis=1, keepdims=1)
。また、列の正規化はnew_matrix = a / a.sum(axis=0, keepdims=1)
で実行できます。これが盛り上がることを願っています。
行列の転置も使用できます。
(a.T / row_sums).T