2

How can a function that operates on 2D arrays (cdist) be applied along an axis of a 3D array ?

I tried with numpy.apply_along_axis , but I need to operate on 2D arrays, not 1D. I obtained the result I need by iterating along one axis, but I would prefer it vectorized if possible:

from scipy import spatial
import numpy as np

a = np.random.randn(600).reshape(10, 20, 3)
distances = np.array([spatial.distance.cdist(a[i,:,:], a[i,:,:]) for i in range(a.shape[0])])

3
  • Do You have a coordinate system with 10x20 points? And do You now want to compute the distance of these points along the dimension of N=20? (by any chance :D ) Commented Nov 14, 2019 at 7:57
  • Yup, you got met :D Commented Nov 14, 2019 at 9:31
  • glad the answer from Divakar fit Your purporse then! Commented Nov 14, 2019 at 9:45

1 Answer 1

5

Inspired by this post, we can solve it in a vectorized manner. So, following the wiki contents from eucl_dist package (disclaimer: I am its author), we could leverage matrix-multiplication and some NumPy specific implementations, like so -

a_s = np.einsum('ijk,ijk->ij',a,a)
sq_dists = a_s[...,None]+a_s[...,None,:]-2*np.einsum('ijk,ilk->ijl',a,a)
dists = np.sqrt(sq_dists)

Alternative(s) :

  • We can use np.matmul/@-operator on Python3.x to replace the matrix-multiplication part. Hence, np.einsum('ijk,ilk->ijl',a,a) could be replaced by np.matmul(a,a.transpose(0,2,1)).
Sign up to request clarification or add additional context in comments.

1 Comment

That did it, thank you very much ! I'd never have guessed it by myself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.