简体   繁体   中英

Perform element-wise subtract from the vector

I need to calculate the sum of elementwise subtracts from the vector from the following equitation:

sum(y(i) - y(j)) at i!=j

y is given as a numpy array
One option is to iterate through the double loop:

dev = 0

for i in range(y.shape[0]):
   for j in range(y.shape[0]):
      if i == j:
         continue
      dev += y[i, j] - y[i, j]

That is definitely not the optimal solution.
How it can be optimized using vectorized operations with numpy vectors?

Say y is flat, eg

>>> y = np.arange(10)
>>> y
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> y.shape
(10,)

You could compute the "cartesian differences" as follows


>>> m = np.abs(y[:, None] - y[None, :])
>>> m
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
       [1, 0, 1, 2, 3, 4, 5, 6, 7, 8],
       [2, 1, 0, 1, 2, 3, 4, 5, 6, 7],
       [3, 2, 1, 0, 1, 2, 3, 4, 5, 6],
       [4, 3, 2, 1, 0, 1, 2, 3, 4, 5],
       [5, 4, 3, 2, 1, 0, 1, 2, 3, 4],
       [6, 5, 4, 3, 2, 1, 0, 1, 2, 3],
       [7, 6, 5, 4, 3, 2, 1, 0, 1, 2],
       [8, 7, 6, 5, 4, 3, 2, 1, 0, 1],
       [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]])

and finally

>>> dev = m.sum()/2
>>> dev
165.0

using itertools combination :

import itertools
sum([x2 - x1 for x1, x2 in itertools.combinations(y, 2)])

using np.subtract.outer

np.abs(np.subtract.outer(y,y)).sum()/2

Time Comparison:

Method 1 (Using Itertools):

Wall time: 18.9 s

Method 2 (Using KeepAlive's cartesian differences):

Wall time: 491 ms

Method 3 (Using np.subtract.outer):

Wall time: 467 ms

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM