I'm looking for efficient alternate ways to compute cosine angle between 2D vectors. Your insights on this problem will be of much help.
vectors
is a 2D array where vectors are stored. The shape of the vectors
array is (N, 2)
where N
is the number of vectors. vectors[:, 0]
has x-component and vectors[:, 1]
has y-component.
I have to find the angle between all the vectors in vectors
. For example, if there are three vectors A, B, C in vectors
, I need to find the angle between A and B
, B and C
, and, A and C
.
I have implemented it and wants to know alternative ways.
vectors = np.array([[1, 3], [2, 4], [3, 5]])
vec_x = vectors[:, 0]
vec_y = vectors[:, 1]
a1 = np.ones([vec_x.shape[0], vec_x.shape[0]]) * vec_x
a2 = np.ones([vec_x.shape[0], vec_x.shape[0]]) * vec_y
a1b1 = a1 * a1.T
a2b2 = a2 * a2.T
mask = np.triu_indices(a1b1.shape[0], 0) # We are interested in lower triangular matrix
a1b1[mask] = 0
a2b2[mask] = 0
numer = a1b1 + a2b2
denom = np.ones([vec_x.shape[0], vec_x.shape[0]]) * np.sqrt(np.square(a1) + np.square(a2))
denom = denom * denom.T
denom[mask] = 0
eps = 1e-7
dot_res = np.rad2deg(np.arccos(np.divide(numer, denom + eps)))
dot_res[mask] = 0
print(dot_res)
[[ 0. 0. 0. ]
[ 8.13010519 0. 0. ]
[12.52880911 4.39870821 0. ]]
Is there any alternative way to do this more efficient?
Can we improve the speed of the current version in some way?
Use scipy.spatial.distance.pdist
:
import numpy as np
import scipy.spatial.distance
vectors = np.array([[1, 3], [2, 4], [3, 5]])
# Compute cosine distance
dist = scipy.spatial.distance.pdist(vectors, 'cosine')
# Compute angles
angle = np.rad2deg(np.arccos(1 - dist))
# Make it into a matrix
angle_matrix = scipy.spatial.distance.squareform(angle)
print(angle_matrix)
# [[ 0. 8.13010235 12.52880771]
# [ 8.13010235 0. 4.39870535]
# [12.52880771 4.39870535 0. ]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With