繁体   English   中英

如何在python中规范化二维numpy数组不那么冗长?

[英]How to normalize a 2-dimensional numpy array in python less verbose?

给定一个 3 乘以 3 的 numpy 数组

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

# array([[ 0,  3,  6],
#        [ 9, 12, 15],
#        [18, 21, 24]])

为了规范化我想到的二维数组的行

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

一定有更好的方法,不是吗?

也许要澄清:通过规范化我的意思是,每行条目的总和必须是一个。 但我认为这对大多数人来说都是清楚的。

广播对此非常有用:

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

row_sums[:, numpy.newaxis]将 row_sums 从(3,)重塑为(3, 1) 当您执行a / bab相互广播。

您可以在此处了解有关广播的更多信息或者在此处了解更多信息。

Scikit-learn 提供了一个函数normalize()可以让您应用各种规范化。 “使之和为 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.]) 

我认为您可以通过以下方式将行元素总和归一化为 1: new_matrix = a / a.sum(axis=1, keepdims=1) 列规范化可以通过new_matrix = a / a.sum(axis=0, keepdims=1) 希望这能帮上忙。

您可以使用内置的 numpy 函数: np.linalg.norm(a, axis = 1, keepdims = True)

看来这也有效

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

您还可以使用矩阵转置:

(a.T / row_sums).T

或者使用 lambda 函数,比如

>>> 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 的每个向量都有一个单位范数。

这是使用reshape另一种可能方法:

a_norm = (a/a.sum(axis=1).reshape(-1,1)).round(3)
print(a_norm)

或者使用None也有效:

a_norm = (a/a.sum(axis=1)[:,None]).round(3)
print(a_norm)

输出

array([[0.   , 0.333, 0.667],
       [0.25 , 0.333, 0.417],
       [0.286, 0.333, 0.381]])

我们可以通过与主对角线是行和的倒数的对角矩阵进行预乘来达到相同的效果。

A = np.diag(A.sum(1)**-1) @ A
normed_matrix = normalize(input_data, axis=1, norm='l1')
print(normed_matrix)

其中 input_data 是二维数组的名称

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM