Given a 2-dimensional array in python, I would like to normalize each row with the following norms:
- Norm 1: L_1
- Norm 2: L_2
- Norm Inf: L_Inf
I have started this code:
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
Output:
(5, 4) # array dimension [12 20 13 44 42] # L1 on each Row
How can I modify the code such that WITHOUT using LOOP, I can directly have the rows of the matrix normalized? (Given the norm values above)
I tried :
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]]
but the output is zero.
>>> np.abs(X).sum(axis=1) array([12, 20, 13, 44, 42])
>>> np.sqrt((X * X).sum(axis=1)) array([ 7.07106781, 10.09950494, 7.41619849, 27.67670501, 27.45906044])
This is the L∞ norm:
>>> np.abs(X).max(axis=1) array([ 6, 6, 5, 25, 25])
>>> 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.])
edit: Better is the method from ayhan if you have it available:
>>> from numpy.linalg import norm >>> norm(X, axis=1, ord=1) array([12, 20, 13, 44, 42]) >>> norm(X, axis=1, ord=2) array([ 7.07106781, 10.09950494, 7.41619849, 27.67670501, 27.45906044]) >>> norm(X, axis=1, ord=np.inf) array([ 6, 6, 5, 25, 25])
edit2: You got zero values because you did integer division. Here's how to avoid that:
>>> 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. ]])
You can pass axis=1
parameter:
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])