How can I calculate the 1-norm of the difference of two vectors, ||a - b||_1 = sum(|a_i - b_i|) in Python?
a = [1,2,3,4]
b = [2,3,4,5]
||a - b||_1 = 4
Python has powerful built-in types, but Python lists are not mathematical vectors or matrices. You could do this with lists, but it will likely be cumbersome for anything more than trivial operations.
If you find yourself needing vector or matrix arithmetic often, the standard in the field is NumPy, which probably already comes packaged for your operating system the way Python also was.
I share the confusion of others about exactly what it is you're trying to do, but perhaps the numpy.linalg.norm function will help:
>>> import numpy
>>> a = numpy.array([1, 2, 3, 4])
>>> b = numpy.array([2, 3, 4, 5])
>>> numpy.linalg.norm((a - b), ord=1)
4
To show how that's working under the covers:
>>> a
array([1, 2, 3, 4])
>>> b
array([2, 3, 4, 5])
>>> (a - b)
array([-1, -1, -1, -1])
>>> numpy.linalg.norm((a - b))
2.0
>>> numpy.linalg.norm((a - b), ord=1)
4
In NumPy, for two vectors a and b, this is just
numpy.linalg.norm(a - b, ord=1)
You appear to be asking for the sum of the differences between the paired components of the two arrays:
>>> A=[1,2,3,4]
>>> B=[2,3,4,5]
>>> sum(abs(a - b) for a, b in zip(A, B))
4
It is not clear what exactly is required here, but here is my guess
a=[1,2,3,4]
b=[2,3,4,5]
def a_b(a,b):
return sum(map(lambda a:abs(a[0]-a[1]), zip(a,b)))
print a_b(a,b)
Using Numpy you can calculate any norm between two vectors using the linear algebra package.
import numpy as np
a = np.array([[2,3,4])
b = np.array([0,-1,7])
# L1 Norm
np.linalg.norm(a-b, ord=1)
# L2 Norm
np.linalg.norm(a-b, ord=2)
# L3 Norm
np.linalg.norm(a-b, ord=3)
# Ln Norm
np.linalg.norm(a-b, ord=n)
Example:
Related
This question already has an answer here:
Multiple matrix multiplication
(1 answer)
Closed 3 years ago.
I have 2 arrays, one of shape (4, 2, 2), another of shape (4, 2).
A = np.random.rand(4, 2, 2)
B = np.random.rand(4, 2)
So, for every 0<= i <= 3, I want to have np.dot(A[i, :, :], B[i, :]).
How to do it without using a for-loop?
(A # B[...,np.newaxis])[...,0] should work (synactic sugar for np.matmul(A, B[...,np.newaxis])[...,0]).
Per the documentation for matmul:
If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes.
You can also use Einstein summation np.einsum("ijk,ik->ij", A, B), although on my machine this is apparently slower than broadcasting matmul:
import timeit
import numpy as np
A = np.random.rand(4, 2, 2)
B = np.random.rand(4, 2)
def broadcast_matmul():
return (A # B[..., np.newaxis])[..., 0]
def list_map():
return np.array(list(map(np.dot, A, B)))
def einsum():
return np.einsum("ijk,ik->ij", A, B)
print(timeit.timeit(broadcast_matmul))
print(timeit.timeit(list_map))
print(timeit.timeit(einsum))
# Results on my machine:
# 1.870921753
# 6.705698656999999
# 2.765732645
Here's how this could be done using np.einsum:
np.einsum('ijk,ik->ij', A, B)
array([[0.39437083, 0.45360039],
[0.75211742, 0.40669922],
[0.18131254, 0.19473085],
[0.2919673 , 0.10398859]])
Quick check using the first elements that are multiplied:
np.dot(A[0], B[0])
# array([0.39437083, 0.45360039])
This should do the trick:
list(map(np.dot, A, B))
Here a simple example
import numpy as np
x=np.random.rand(5,5)
k,p = np.where(x>0.5)
k and p are arrays of indices
Now I have a list of rows which should be considered m=[0,2,4], so I need to find all entries of k which are in the list m.
I came up with a very simple but horrible inefficient solution
d = np.array([ (a,b) for a,b in zip(k,p) if a in m])
The solution works, but very slow. I’m looking for a better and more efficient one. I need to do a few millions of such operations with dynamically adjusted m, so efficiency of an algorithm is really a critical question.
Maybe the below is faster:
d=np.dstack((k,p))[0]
print(d[np.isin(d[:,0],m)])
You could use isin() to get a boolean mask which you can use to index k.
>>> x=np.random.rand(3,3)
>>> x
array([[0.74043564, 0.48328081, 0.82396324],
[0.40693944, 0.24951958, 0.18043229],
[0.46623863, 0.53559775, 0.98956277]])
>>> k, p = np.where(x > 0.5)
>>> p
array([0, 2, 1, 2])
>>> k
array([0, 0, 2, 2])
>>> m
array([0, 1])
>>> np.isin(k, m)
array([ True, True, False, False])
>>> k[np.isin(k, m)]
array([0, 0])
How about:
import numpy as np
m = np.array([0, 2, 4])
k, p = np.where(x[m, :] > 0.5)
k = m[k]
print(zip(k, p))
This only considers the interesting rows (and then zips them to 2d indices).
have two arrays that are like this
x = [a,b]
y = [p,q,r]
I need to multiply this together to a product c which should be like this,
c = [a*p, a*q, a*r, b*p, b*q, b*r]
However x*y gives the following error,
ValueError: operands could not be broadcast together with shapes (2,) (3,)
I can do something like this,
for i in range(len(x)):
for t in range(len(y)):
c.append(x[i] * y[t]
But really the length of my x and y is quite large so what's the most efficient way to make such a multiplication without the looping.
You can use NumPy broadcasting for pairwise elementwise multiplication between x and y and then flatten with .ravel(), like so -
(x[:,None]*y).ravel()
Or use outer product and then flatten -
np.outer(x,y).ravel()
Use Numpy dot...
>>> import numpy as np
>>> a=np.arange(1,3)# [1,2]
>>> b=np.arange(1,4)# [1,2,3]
>>> np.dot(a[:,None],b[None])
array([[1, 2, 3],
[2, 4, 6]])
>>> np.dot(a[:,None],b[None]).ravel()
array([1, 2, 3, 2, 4, 6])
>>>
I wish to initialise a matrix A, using the equation A_i,j = f(i,j) for some f (It's not important what this is).
How can I do so concisely avoiding a situation where I have two for loops?
numpy.fromfunction fits the bill here.
Example from doc:
>>> import numpy as np
>>> np.fromfunction(lambda i, j: i + j, (3, 3), dtype=int)
array([[0, 1, 2],
[1, 2, 3],
[2, 3, 4]])
One could also get the indexes of your array with numpy.indices and then apply the function f in a vectorized fashion,
import numpy as np
shape = 1000, 1000
Xi, Yj = np.indices(shape)
A = (2*Xi + 3*Yj).astype(np.int) # or any other function f(Xi, Yj)
I am looking for a way to achieve the following in Python and can't figure out how to do it:
a=[[0,1],[1,0],[1,1]]
b=[1,0,5]
c=hocuspocus(a,b)
--> c=[[0,1],[0,0],[5,5]]
So basically I would like to multiply the different matrix rows in a with the list b.
Thanks a lot in advance!
hocuspocus = lambda a,b: [[r*q for r in p] for p, q in zip(a,b)]
Use Numpy, it has a function for cross multiplying, and other useful tools for matricies.
import * from numpy as np
a=[[0,1],[1,0],[1,1]]
b=[1,0,5]
prod = a * b
Python lists don't support that behaviour directly, but Numpy arrays do matrix multiplication (and various other matrix operations that you might want) directly:
>>> a
array([[0, 1, 1],
[1, 0, 1]])
>>> b
array([1, 0, 5])
>>> a * b
array([[0, 0, 5],
[1, 0, 5]])