I've been given 2 different 2D arrays and I'm asked to calculate the L2 distance between the rows of array x and the rows in array y. The shape of array x is (M, D) and the shape of array y is (N, D). The final answer array should have the shape (M, N).
I'm not very good at python. I'm really just doing random things and seeing what happens.
import numpy as np
def compute_distances(x, y):
""" Write a function that computes the L2 distance between each row
in `x` and `y`.
Parameters
----------
x : numpy.ndarray
x.shape must be (M, D)
Each row of `x` is a flattened vector representing the pixel
values of a single image. Thus `x` represents
M images, each one described by a length-D vector.
y : numpy.ndarray
y.shape must be (N, D)
Each row of `y` is a flattened vector representing the pixel
values of a single image. Thus `y` represents
N images, each one described by a length-D vector.
Returns
-------
distances : numpy.ndarray
distances.shape = (M, N)
distances[i, j] = the L2 distance between x[i] and y[j]
"""
# student code goes here
M = x.shape[0]
N = y.shape[0]
dists = np.array (M, N)
dists[i, j] = np.sqrt(np.sum(np.square(x.shape[0] - y.shape[0]), axis = 0))
pass
I like this one since it works for 1, 2 and 3D arrays
def e_dist(a, b, metric='euclidean'):
"""Distance calculation for 1D, 2D and 3D points using einsum
preprocessing :
use `_view_`, `_new_view_` or `_reshape_` with structured/recarrays
Parameters
----------
a, b : array like
Inputs, list, tuple, array in 1, 2 or 3D form
metric : string
euclidean ('e', 'eu'...), sqeuclidean ('s', 'sq'...),
Notes
-----
mini e_dist for 2d points array and a single point
>>> def e_2d(a, p):
diff = a - p[np.newaxis, :] # a and p are ndarrays
return np.sqrt(np.einsum('ij,ij->i', diff, diff))
See Also
--------
cartesian_dist : function
Produces pairs of x,y coordinates and the distance, without duplicates.
"""
a = np.asarray(a)
b = np.atleast_2d(b)
a_dim = a.ndim
b_dim = b.ndim
if a_dim == 1:
a = a.reshape(1, 1, a.shape[0])
if a_dim >= 2:
a = a.reshape(np.prod(a.shape[:-1]), 1, a.shape[-1])
if b_dim > 2:
b = b.reshape(np.prod(b.shape[:-1]), b.shape[-1])
diff = a - b
dist_arr = np.einsum('ijk,ijk->ij', diff, diff)
if metric[:1] == 'e':
dist_arr = np.sqrt(dist_arr)
dist_arr = np.squeeze(dist_arr)
return dist_arr
Yielding
a = np.random.rand(3, 2)
b = np.random.rand(5, 2)
e_dist(a, b)
array([[0.62, 0.45, 0.88, 0.7 , 0.33],
[0.46, 0.57, 0.47, 0.25, 0.4 ],
[0.94, 0.68, 0.16, 0.35, 0.62]])
and for...
a = np.random.rand(2, 3, 2)
b = np.random.rand(2, 5, 2)
e_dist(a, b)
array([[0.72, 0.39, 0.89, 0.25, 0.29, 0.41, 0.31, 0.6 , 0.8 , 0.39],
[0.25, 0.26, 0.69, 0.45, 0.45, 0.63, 0.57, 0.39, 0.25, 0.78],
[0.28, 0.27, 0.74, 0.47, 0.46, 0.69, 0.62, 0.45, 0.25, 0.84],
[0.43, 0.48, 0.47, 0.52, 0.54, 0.2 , 0.17, 0.21, 0.55, 0.38],
[0.15, 0.36, 0.54, 0.51, 0.52, 0.52, 0.48, 0.23, 0.23, 0.69],
[0.87, 0.76, 0.78, 0.67, 0.71, 0.26, 0.28, 0.64, 0.99, 0.06]])
And to compare numpy and scipy variants for 2d
from scipy.spatial import distance_matrix
distance_matrix(a, b)
array([[0.87, 0.89, 0.91, 0.07, 0.68, 0.95, 0.89],
[0.78, 0.52, 0.28, 0.85, 0.22, 0.65, 0.51],
[0.75, 0.46, 0.51, 1.08, 0.5 , 0.57, 0.45]])
e_dist(a, b)
array([[0.87, 0.89, 0.91, 0.07, 0.68, 0.95, 0.89],
[0.78, 0.52, 0.28, 0.85, 0.22, 0.65, 0.51],
[0.75, 0.46, 0.51, 1.08, 0.5 , 0.57, 0.45]])
So there are lots of options, depending on the size of the arrays you are working with.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.