0

I have two numpy arrrays:

import numpy as np
points_1 = np.array([1.5,2.5,1,3])
points_2 = np.array([3,4])

I would like to take evey point from points_1 array and deduce whole points_2 array from it in order to get a matrix I would like to get

[[-1.5,-2.5]
 [-0.5,-1.5]
 [-2 , -3]
 [0 , -1]]

I know there is a way with iteration

points = [x - points_2 for x  in points_1] 
points = np.array(points)

However this option is not fast enough. In reality I am using much bigger arrays. Is there some fastser way? Thanks!

Rory Daulton
  • 21,934
  • 6
  • 42
  • 50
David
  • 1

5 Answers5

0

You just have to chose points_2 "better" (better means here an other dimension of you matrix), then it works as you expect it:

so do not use points_2 = np.array([3, 4]) but points_2 = np.array([[3],[4]]):

import numpy as np
points_1 = np.array([1.5,2.5,1,3])
points_2 = np.array([[3],[4]])
points = (points_1 - points_2).transpose()

print(points)

results in:

[[-1.5 -2.5]
 [-0.5 -1.5]
 [-2.  -3. ]
 [ 0.  -1. ]]
user69453
  • 1,279
  • 1
  • 17
  • 43
  • Is there a fast way of converting `np.array([3, 4])` into `np.array([[3],[4]])` – David Nov 18 '18 at 13:04
  • You can do: `points_2 = np.array([3, 4])` and then `points = (points_1 - points_2[:, np.newaxis]).transpose()`. Should I update my answer? – user69453 Nov 18 '18 at 13:25
0

If you don't the whole array at once. You can use generators and benefit from lazy evaluation:

import numpy as np
points_1 = np.array([1.5,2.5,1,3])
points_2 = np.array([3,4])

def get_points():
    def get_points_internal():
        for p1 in points_1:
            for p2 in points_2:
                yield [p1 - p2]

    x = len(points_1) * len(points_2)
    points_1d = get_points_internal()
    for i in range(0, int(x/2)):
        yield [next(points_1d), next(points_1d)]

points = get_points()
Andrzej Gis
  • 13,706
  • 14
  • 86
  • 130
0

Make use of numpy's broadcasting feature. This will provide the following:

import numpy as np
points_1 = np.array([1.5,2.5,1,3])
points_2 = np.array([3,4])

points = points_1[:, None] - points_2
print(points)

Output:

 [[-1.5 -2.5]
 [-0.5 -1.5]
 [-2.  -3. ]
 [ 0.  -1. ]]

It works by repeating the operation over the 1 dimension injected by the None index. For more info see the link.

cvanelteren
  • 1,633
  • 9
  • 16
0

You can do it in one line :

np.subtract.outer(points_1,points_2)

This is vectored so very fast.

B. M.
  • 18,243
  • 2
  • 35
  • 54
0

You need to use tranposed matrix.

points_1-np.transpose([points_2])

and for your result

np.tanspose(points_1-np.transpose([points_2]))
robobrno
  • 61
  • 9