-2

Let A be a matrix:

A = array([[0.        , 0.        , 0.        , ..., 0.        , 0.        ,
    0.        ],
   [0.        , 0.28867513, 0.28867513, ..., 0.        , 0.        ,
    0.        ],
   [0.        , 0.        , 0.        , ..., 0.        , 0.        ,
    0.        ],
   [0.        , 0.        , 0.        , ..., 0.        , 0.        ,
    0.        ],
   [0.        , 0.13363062, 0.13363062, ..., 0.        , 0.        ,
    0.        ]])

B = array([0.70710678, 0.66666667, 0.5       , 0.75      , 1.        ])

I need to find the indexes of B in A.

Expected Output:

Matrix containing position of elements.

I want to perform this using inbuilt numpy commands/ logic and not using list comprehension or for loops.

Update: Already tried using isin, unable to tackle multiple elements with same value in the same row.

Updated with a better example of the problem.

Atom
  • 57
  • 7
  • By find the values of B do you mean the first 0 and then the second 0 in A etc.? or the whole sequence 0,0,0,1,1 in this order in A? – SiP Nov 14 '22 at 11:34
  • B is the values whose index I intend to find from the matrix A. I want to iterate by row and find position of the elements in B which are in A. – Atom Nov 14 '22 at 11:35
  • So the length of B is the same as the number of columns in A? So you're looking for a row in A? – SiP Nov 14 '22 at 11:36
  • the shape of A is (507, 5434), the shape of B is (507,) – Atom Nov 14 '22 at 11:37
  • Are you looking for rows in A that are equal to B? – SiP Nov 14 '22 at 11:38
  • Yes, precisely row-wise index of the values which are equal to B. – Atom Nov 14 '22 at 11:39
  • Your original example made (some) sense. This generalization does not. We could reproduce the original; we can't copy your new arrays, much less recreate a vague "matrix" result. Something to keep in mind is that exact matches with floats is difficult. `np.isclose/np.allclose` are the best tools for comparing float arrays. – hpaulj Nov 15 '22 at 16:28

2 Answers2

2

numpy.all has a axis input so you can check if a row/column is all True. To get the index of the row you can use np.where

np.where(np.all(A==B, axis=1))
SiP
  • 1,080
  • 3
  • 8
  • This was a relatively simple example; I am trying to perform this operation on a large matrix where there are multiple values being repeated. Already tried performing this it didn't come through. – Atom Nov 14 '22 at 11:26
  • Then you should ask the full question you want answered... Are the values in B unique? if yes, then this answer should work. Otherwise, edit the question with more info – SiP Nov 14 '22 at 11:29
  • sorry about that. I have updated the question. – Atom Nov 14 '22 at 11:31
  • Edited to answer the edited question – SiP Nov 14 '22 at 11:51
  • There's possibly a faster wat but for the dimensions you mentioned this should be very fast – SiP Nov 14 '22 at 11:52
  • This returns an error " axis 1 is out of bounds for array of dimension 0", tried modifying the dimensions too.. still stuck with the same error. – Atom Nov 14 '22 at 12:41
  • You have a problem of dimensions, for this to work you must have `len(B)==A.shape[1]` – SiP Nov 14 '22 at 12:53
  • I tried applying transposition to meet the above conditions as you mentioned, I am returned with an empty array – Atom Nov 15 '22 at 07:03
  • Then there are probably no matches... Try matching the first row from A to A itself, it should return the index 0.. – SiP Nov 15 '22 at 07:38
0

With your original example

In [436]: A = [[0, 1, 2, 3],
     ...:      [4, 5, 6, 7],
     ...:      [8, 9, 10, 11]]
     ...: 
     ...: B = [2, 5, 11]

A simple list comprehension produces:

In [437]: [a.index(b) for a,b in zip(A,B)]
Out[437]: [2, 1, 3]

index does only gives the first, and raises an error if there isn't a match. We could write a cover function that addresses those issue, catching the error, and repeating itself.

If the inputs are arrays:

In [438]: AA = np.array(A); BB = np.array(B)

We can do a "row-wise" test:

In [439]: BB[:,None]==AA
Out[439]: 
array([[False, False,  True, False],
       [False,  True, False, False],
       [False, False, False,  True]])

and find all the True. Your [2,1,3] is the 2nd array.

In [440]: np.nonzero(_)
Out[440]: (array([0, 1, 2], dtype=int64), array([2, 1, 3], dtype=int64))

again the match isn't so clean with there are variable numbers of matches per row.

If the values are floats, we could use isclose instead:

In [441]: np.isclose(BB[:,None],AA)
Out[441]: 
array([[False, False,  True, False],
       [False,  True, False, False],
       [False, False, False,  True]])

Get all indexes of multiple values in numpy array

seeks multiple matches between two arrays. Both arrays are 1d, but the responses illustrate the complications in working with multiple matches.

hpaulj
  • 221,503
  • 14
  • 230
  • 353