JAWE
JAWE

Reputation: 293

Find ordered vector in numpy array

I need to find a vector in a numpy.array. For example, I have a np.array named e and I want to find the vector [1, 2] in e (meaning that I would like to have the index of the vector inside the matrix) but apparently my programm see the vector even when is not present:

enter image description here

The code I use to built e in the following:

import numpy as np
faces = np.array([[1,2,3,4],[5,6,2,1],[6,7,3,2],[7,8,4,3],[8,5,1,4],[8,7,6,5]])
e = np.zeros([6,4,2])
for k in range(len(faces)):
    a = [faces[k][0], faces[k][1]]
    b = [faces[k][1], faces[k][2]] 
    c = [faces[k][2], faces[k][3]]
    d = [faces[k][3], faces[k][0]]
    e[k] = np.array([a,b,c,d])
 print('e: %s' %e)

any clue how to solve this?

Upvotes: 5

Views: 6041

Answers (4)

CT Zhu
CT Zhu

Reputation: 54380

Try:

e[np.all((e-np.array([1,2]))==0, axis=2)]

Brief explanation. e-np.array([1,2]) returns [0,0] where it is [1,2] in array e. np.all(..., axis=2 returns the Boolean array: True if [0,0] False otherwise (so things such as [1,1] will become False). Finally, just slice it from e.

To get the index of [1,2]'s (there may be multiple sub vector [1,2]):

np.argwhere(np.all((e-array([1,2]))==0, axis=2))

Upvotes: 4

Dan Allan
Dan Allan

Reputation: 35255

Don't use Python in with numpy arrays.

There are 6 x 4 pairs in e.

In [32]: e.shape
Out[32]: (6, 4, 2)

You are looking an element that matches both (i.e., all()) entries in the pair [1, 2].

In [33]: (e == np.array([1, 2])).all(-1)
Out[33]: 
array([[ True, False, False, False],
       [False, False, False, False],
       [False, False, False, False],
       [False, False, False, False],
       [False, False, False, False],
       [False, False, False, False]], dtype=bool)

The -1 in all(-1) refers the last dimension in the array, the part of the shape that constitutes pairs. Using -1 is probably more general than using 2, which would also work in this case.

It found the right match -- the only True value. You can see the shape of this result makes sense.

In [34]: (e == np.array([1, 2])).all(-1).shape
Out[34]: (6, 4)

To get the index of the first match you could do

x, y = (e == np.array([1, 2])).all(-1).argmax(1).argmax(), (e == np.array([1, 2])).all(-1).argmax(0).argmax()

but using np.argwhere suggested in CT Zhu's answer is definitely better.

Upvotes: 6

Jaime
Jaime

Reputation: 67457

You can also use the following trick to view your vectors as single items of np.void dtype:

e = np.ascontiguousarray(e)
dt = np.dtype((np.void, e.dtype.itemsize * e.shape[-1]))
e_view = e.view(dt)
search = np.array([1, 2], dtype=e.dtype).view(dt)

You can now extract the positions with np.in1d:

mask = np.in1d(e_view, search)
indices = np.unravel_index(np.where(mask), e.shape[:-1])

>>> indices
(array([[0]], dtype=int64), array([[0]], dtype=int64))

The return arrays is a tuple with the rows and columns of the occurrences of search, in this case there is only one, at (0, 0).

Upvotes: 2

Garth5689
Garth5689

Reputation: 622

This will print out all the indices of e and whether it is equal to [1,2]. If you wanted to return the indices, instead of printing them, you could add (num, num2) to another list, and that would give you all the locations of [1,2]. Would need to be extended to work with arrays of more levels.

for num, item in enumerate(e):
    for num2, item2 in enumerate(item):                                    
        print ('e[{i}][{j}]: {truth}'.format(i=num, 
                                             j=num2, 
                                             truth = (item2 == [1,2]).all()))

Output:

e[0][0]: True                                                                                                          
e[0][1]: False                                                                                                         
e[0][2]: False                                                                                                         
e[0][3]: False                                                                                                         
e[1][0]: False                                                                                                         
e[1][1]: False                                                                                                         
e[1][2]: False                                                                                                         
e[1][3]: False                                                                                                         
e[2][0]: False                                                                                                         
e[2][1]: False                                                                                                         
e[2][2]: False                                                                                                         
e[2][3]: False                                                                                                         
e[3][0]: False                                                                                                         
e[3][1]: False                                                                                                         
e[3][2]: False                                                                                                         
e[3][3]: False                                                                                                         
e[4][0]: False                                                                                                         
e[4][1]: False                                                                                                         
e[4][2]: False                                                                                                         
e[4][3]: False                                                                                                         
e[5][0]: False                                                                                                         
e[5][1]: False                                                                                                         
e[5][2]: False                                                                                                         
e[5][3]: False

Upvotes: 0

Related Questions