NumPy: how to quickly normalize many vectors?

前端 未结 6 973
梦毁少年i
梦毁少年i 2021-01-31 04:47

How can a list of vectors be elegantly normalized, in NumPy?

Here is an example that does not work:

from numpy import *

vectors = array([arange         


        
6条回答
  •  走了就别回头了
    2021-01-31 05:46

    Computing the magnitude

    I came across this question and became curious about your method for normalizing. I use a different method to compute the magnitudes. Note: I also typically compute norms across the last index (rows in this case, not columns).

    magnitudes = np.sqrt((vectors ** 2).sum(-1))[..., np.newaxis]
    

    Typically, however, I just normalize like so:

    vectors /= np.sqrt((vectors ** 2).sum(-1))[..., np.newaxis]
    

    A time comparison

    I ran a test to compare the times, and found that my method is faster by quite a bit, but Freddie Witherdon's suggestion is even faster.

    import numpy as np    
    vectors = np.random.rand(100, 25)
    
    # OP's
    %timeit np.apply_along_axis(np.linalg.norm, 1, vectors)
    # Output: 100 loops, best of 3: 2.39 ms per loop
    
    # Mine
    %timeit np.sqrt((vectors ** 2).sum(-1))[..., np.newaxis]
    # Output: 10000 loops, best of 3: 13.8 us per loop
    
    # Freddie's (from comment below)
    %timeit np.sqrt(np.einsum('...i,...i', vectors, vectors))
    # Output: 10000 loops, best of 3: 6.45 us per loop
    

    Beware though, as this StackOverflow answer notes, there are some safety checks not happening with einsum, so you should be sure that the dtype of vectors is sufficient to store the square of the magnitudes accurately enough.

提交回复
热议问题