web-dev-qa-db-ja.com

python冗長性の少ない2次元のnumpy配列を正規化する方法は?

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でなければなりません。しかし、それはほとんどの人にとって明らかだと思います。

78
Aufwind

放送はこれに本当に適しています。

row_sums = a.sum(axis=1)
new_matrix = a / row_sums[:, numpy.newaxis]

row_sums[:, numpy.newaxis]は、row_sumsを(3,)から(3, 1)に変更します。 a / bを実行すると、abが互いにブロードキャストされます。

broadcastinghere の詳細をご覧くださいまたはさらに良い here .

120
Bi Rico

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になります。

82
rogueleaderr

これでうまくいくと思う

a = numpy.arange(0,27.,3).reshape(3,3)

a /=  a.sum(axis=1)[:,numpy.newaxis]
9
tom10

大きさが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.]) 
3
walt

これも機能するようです

def normalizeRows(M):
    row_sums = M.sum(axis=1)
    return M / row_sums
1
Jamesszm

または、ラムダ関数を使用して、

>>> 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の各ベクトルには単位ノルムがあります。

0
XY.W

これにより、行要素の合計を1に正規化できると思います:new_matrix = a / a.sum(axis=1, keepdims=1)。また、列の正規化はnew_matrix = a / a.sum(axis=0, keepdims=1)で実行できます。これが盛り上がることを願っています。

0
Fanwang Meng

行列の転置も使用できます。

(a.T / row_sums).T
0
Maciek