规范化矩阵python的行

时间:2016-03-28 17:54:53

标签: python numpy python-2.x

在python中给出一个二维数组,我想用以下规范标准化每一行:

  • 规范1: L_1
  • 规范2: L_2
  • Norm Inf: L_Inf

我已经开始使用此代码:

from numpy import linalg as LA
X = np.array([[1, 2, 3, 6],
              [4, 5, 6, 5],
              [1, 2, 5, 5],
              [4, 5,10,25],
              [5, 2,10,25]])

print X.shape
x = np.array([LA.norm(v,ord=1) for v in X])
print x

输出:

   (5, 4)             # array dimension
   [12 20 13 44 42]   # L1 on each Row

如何修改代码,使得不使用LOOP,我可以直接将矩阵的行标准化? (鉴于上面的标准值)

我试过了:

 l1 = X.sum(axis=1)

 print l1
 print X/l1.reshape(5,1)

 [12 20 13 44 42]
 [[0 0 0 0]
 [0 0 0 0]
 [0 0 0 0]
 [0 0 0 0]
 [0 0 0 0]]

但输出为零。

2 个答案:

答案 0 :(得分:11)

这是L 1范数:

>>> np.abs(X).sum(axis=1)
array([12, 20, 13, 44, 42])

这是L 2规范:

>>> np.sqrt((X * X).sum(axis=1))
array([  7.07106781,  10.09950494,   7.41619849,  27.67670501,  27.45906044])

这是L∞规范:

>>> np.abs(X).max(axis=1)
array([ 6,  6,  5, 25, 25])

要标准化行,只需按标准划分。例如,使用L 2标准化:

>>> l2norm = np.sqrt((X * X).sum(axis=1))
>>> X / l2norm.reshape(5,1)
array([[ 0.14142136,  0.28284271,  0.42426407,  0.84852814],
       [ 0.39605902,  0.49507377,  0.59408853,  0.49507377],
       [ 0.13483997,  0.26967994,  0.67419986,  0.67419986],
       [ 0.14452587,  0.18065734,  0.36131469,  0.90328672],
       [ 0.18208926,  0.0728357 ,  0.36417852,  0.9104463 ]])
>>> np.sqrt((_ * _).sum(axis=1))
array([ 1.,  1.,  1.,  1.,  1.])

norm中的numpy.linalg方法更直接,如果有的话:

>>> from numpy.linalg import norm
>>> norm(X, axis=1, ord=1)  # L-1 norm
array([12, 20, 13, 44, 42])
>>> norm(X, axis=1, ord=2)  # L-2 norm
array([  7.07106781,  10.09950494,   7.41619849,  27.67670501,  27.45906044])
>>> norm(X, axis=1, ord=np.inf)  # L-∞ norm
array([ 6,  6,  5, 25, 25])

(在OP编辑之后):您看到零值,因为/是Python 2.x中的整数除法。要么升级到Python 3,要么将dtype更改为float以避免整数除法:

>>> linfnorm = norm(X, axis=1, ord=np.inf)
>>> X.astype(np.float) / linfnorm[:,None]
array([[ 0.16666667,  0.33333333,  0.5       ,  1.        ],
       [ 0.66666667,  0.83333333,  1.        ,  0.83333333],
       [ 0.2       ,  0.4       ,  1.        ,  1.        ],
       [ 0.16      ,  0.2       ,  0.4       ,  1.        ],
       [ 0.2       ,  0.08      ,  0.4       ,  1.        ]])

答案 1 :(得分:5)

您可以传递axis=1参数:

In [58]: LA.norm(X, axis=1, ord=1)
Out[58]: array([12, 20, 13, 44, 42])


In [59]: LA.norm(X, axis=1, ord=2)
Out[59]: array([  7.07106781,  10.09950494,   7.41619849,  27.67670501,  27.45906044])