Calculate unique connecting vectors for point cloud using numpy

Published: Jan. 26, 2019

If you have a list of points in numpy, you might want to calculate a list of all vectors for unique pairings that connect the points, without the inverse and without the connection to itself, i.e. only a1 -> a2, without a2 -> a1 or a1 -> a1. For that you can use the numpy.mgrid function to generate all index permutations, filter out the ones that fit the criterion, and use Boolean array indexing and integer array indexing to calculate all differences.

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 a = np.array([ [0, 0], [1, 0], [0, 1], [1, 1], [2, 1], [1, 2] ]) # Generate a fleshed out grid with all index pairings i, j = np.mgrid[0:len(a), 0:len(a)] print(i) print(j) ''' [[0 0 0 0 0 0] [1 1 1 1 1 1] [2 2 2 2 2 2] [3 3 3 3 3 3] [4 4 4 4 4 4] [5 5 5 5 5 5]] [[0 1 2 3 4 5] [0 1 2 3 4 5] [0 1 2 3 4 5] [0 1 2 3 4 5] [0 1 2 3 4 5] [0 1 2 3 4 5]] ''' # This creates an array with Boolean values set to "True" for # the index pairings that we want selector = j > i print(selector) ''' [[False True True True True True] [False False True True True True] [False False False True True True] [False False False False True True] [False False False False False True] [False False False False False False]] ''' # Extract the index lists that fit the criterion using the Boolean array i_select = i[selector] j_select = j[selector] print(i_select, j_select) ''' [0 0 0 0 0 1 1 1 1 2 2 2 3 3 4] [1 2 3 4 5 2 3 4 5 3 4 5 4 5 5] ''' # Use the index list for array indexing result = a[i_select] - a[j_select] print(result) ''' [[-1 0] [ 0 -1] [-1 -1] [-2 -1] [-1 -2] [ 1 -1] [ 0 -1] [-1 -1] [ 0 -2] [-1 0] [-2 0] [-1 -1] [-1 0] [ 0 -1] [ 1 -1]] '''