Link_tester
Link_tester

Reputation: 1081

How to compare one row of a numpy array to all the other rows

I have a numpy array with some coordinates (x,y and z):

coord=np.array([[0.,0.,2.], [0.,1.,3.], [0.,2.,2.], [1.,0.,1.], [1.,1.,3.], [2.,0.,1.], [2.,1.,1.], [3.,0.,1.]])
threshold = 1

I want to compare each row of this array with all the next row. Then, in case of satisfying my condition, I want to print the number of rows which the condition is satisfied. I tried the following but it is only comparing one row with the next one rather than all the rows:

for ind, val in enumerate (coord):
    if coord[ind][1] == coord[ind+1][1] and coord[ind+1][0]-coord[ind][1] < 1.2 * threshold:
        print (ind+13, ind+1+14)

I want to start from the first row and check it with all the following rows. Then I want to check the second row with all the following ones and so on. In my condition I want to say if the the present row has the same y value (coord[:,1]) with the next ones and also their x distance (coord[ind+1][0]-coord[ind][1]) is not more than a threshold, print the index of that two pairs (my code call them ind+13, ind+1+13 which is not correct, because I want to add 13 to index of the detected pairs). Finally I want to print such a result:

13, 16
14, 17
16, 18
17, 19
18, 20

I appreciate any help and contribution.

Upvotes: 1

Views: 1388

Answers (2)

jakevdp
jakevdp

Reputation: 86320

When working with NumPy arrays, it is often much more efficient to use broadcasting approaches than Python loops. Here is a solution to your problem that uses broadcasting, and results in an array of the desired indices:

# Compute all indices that meet the conditions
i, j = np.where(
    (coord[:, 1] == coord[:, np.newaxis, 1]) &
    (abs(coord[:, 0] - coord[:, np.newaxis, 0]) < 1.2 * threshold)
)

# Restrict to where i is before j
i, j = i[i < j], j[i < j]

# Combine and print the indices, with 13 added
print(np.vstack([i, j]).T + 13)
# [[13 16]
#  [14 17]
#  [16 18]
#  [17 19]
#  [18 20]]

Upvotes: 2

KaRaOkEy
KaRaOkEy

Reputation: 328

I think what you want is a second loop through your values behind the one you are currently lokking at:

for ind, val in enumerate (coord):
    if ind < len(coord): 
        for ind1, val1 in enumerate (coord[ind+1:]):
            if val[1] == val1[1] and (abs((val[0] - val1[0])) < (1.2 * threshold)):
                print (ind+13, ind+ind1+14)

Upvotes: 1

Related Questions