Find the Index of a Value in a 2D Array

How to find the index of a value in 2d array in Python?

You can use np.where to return a tuple of arrays of x and y indices where a given condition holds in an array.

If a is the name of your array:

>>> np.where(a == 1)
(array([0, 0, 1, 1]), array([0, 1, 2, 3]))

If you want a list of (x, y) pairs, you could zip the two arrays:

>>> zip(*np.where(a == 1))
[(0, 0), (0, 1), (1, 2), (1, 3)]

Or, even better, @jme points out that np.asarray(x).T can be a more efficient way to generate the pairs.

How to get index of Element in two dimensional array?

Show Indices of an element in a 2-dim Array - the complicated way

If I understand correctly, you are looping through a datafield array via a ►For Each construction and want to get the current row/column index pair of that same array.

In order to answer your question

"How to get indices of an element in a two dimensional array",

I leave aside that you would get these automatically in a more evident and usual way if you changed the logic by looping through array rows first and inside this loop eventually through array columns - see Addendum *).

To allow a reconstruction of e.g. the 6th array element in the example call below as referring to the current index pair (element i=6 ~> table1(3,2) ~> row:=3/column:=2) it would be necessary

  • to add an element counter i by incrementing its value by +1 each time you get the next element and
  • to pass this counter as argument (additionally to a reference to the datafield) to a help function getIndex()

returning results as another array, i.e. an array consisting only of two values: (1) the current array row, (2) the current array column:

Example call

Note: For better readibility and in order to condense the answer to the mimimum needed (c.f. MCVE) the following example call executes only one For Each loop over the table1 datafield array; you will be in the position to change this to your needs or to ask another question.

Option Explicit                         ' declaration head of your code module                     

Sub ShowIndicesOf2DimArray()
Dim table1 ' declare variant 1-based 2-dim datafield
table1 = Sheet1.Range("A2:B4") ' << change to sheets Code(Name)

Dim vElem, i As Long
Dim curRow As Long, curCol As Long ' current row/column number
For Each vElem In table1

i = i + 1 ' increment element counter
curRow = getIndex(table1, i)(1) ' <~ get row index via help function
curCol = getIndex(table1, i)(2) ' <~ get col index via help function

'optional debug info in VB Editors immediate window (here: Direktbereich)
Debug.Print i & ". " & _
" Table1(" & curRow & "," & curCol & ") = " & vElem & vbTab;
Debug.Print ", where curRow|curCol are " & Join(getIndex(table1, i), "|")
Next vElem
End Sub

Help function getIndex() called by above procedure

Function getIndex(table1, ByVal no As Long) As Variant
'Purpose: get 1-based 1-dim array with current row+column indices
ReDim tmp(1 To 2)
tmp(1) = (no - 1) Mod UBound(table1) + 1
tmp(2) = Int((no - 1) / UBound(table1) + 1)
getIndex = tmp
End Function

enter image description here

*) Addendum - "the simple way"

Just the other way round using row and column variables r and c as mentioned above; allows to refer to an item simply via table1(r,c) :

Sub TheSimpleWay()
Dim table1 ' declare variant 1-based 2-dim datafield
table1 = Sheet1.Range("A2:B4") ' << change to sheets Code(Name)
Dim vElem, i As Long
Dim r As Long, c As Long ' row and column counter
For r = 1 To UBound(table1) ' start by row 1 (1-based!) up to upper boundary in 1st dimension
For c = 1 To UBound(table1, 2) ' start by col 1 (1-based!) up to upper boundary in 2nd dimension
i = i + 1
Debug.Print i & ". " & _
" Table1(" & r & "," & c & ") = " & table1(r, c) & vbTab;
Debug.Print ", where row|col are " & r & "|" & c

Next c
Next r
End Sub


How to return the index of an element in a 2d array in python?

This worked fine. I wrote a function to return the index for any given element in the array!

Sample Image

Finding indices of values in 2D numpy array

np.where with a single argument is equivalent to np.nonzero. It gives you the indices where a condition, the input array, is True.

In your example you are checking for element-wise equality between a[:,1] and values

a[:, 1] == values
False

So it's giving you the correct result: no index in the input is True.

You should use np.isin instead

np.isin(a[:,1], values)
array([False, False, True, True, False, False, False, False, True, False], dtype=bool)

Now you can use np.where to get the indices

np.where(np.isin(a[:,1], values))
(array([2, 3, 8]),)

and use those to address the original array

a[np.where(np.isin(a[:,1], values))]    
array([[ 1, 97612, 1],
[ 1, 97697, 1],
[ 1, 97944, 1]])

Your initial solution with a simple equality check could indeed have worked with proper broadcasting:

np.where(a[:,1] == values[..., np.newaxis])[1]
array([2, 3, 8])

EDIT: given you seem to have issues with using the above results to index and manipulate your array here's a couple of simple examples

Now you should have two ways of accessing your matching elements in the original array, either the binary mask or the indices from np.where.

mask = np.isin(a[:,1], values)  # np.in1d if np.isin is not available
idx = np.where(mask)

Let's say you want to set all matching rows to zero

a[mask] = 0   # or a[idx] = 0
array([[ 1, 97553, 1],
[ 1, 97587, 1],
[ 0, 0, 0],
[ 0, 0, 0],
[ 1, 97826, 3],
[ 1, 97832, 1],
[ 1, 97839, 1],
[ 1, 97887, 1],
[ 0, 0, 0],
[ 1, 97955, 2]])

Or you want to multiply the third column of matching rows by 100

a[mask, 2] *= 100
array([[ 1, 97553, 1],
[ 1, 97587, 1],
[ 1, 97612, 100],
[ 1, 97697, 100],
[ 1, 97826, 3],
[ 1, 97832, 1],
[ 1, 97839, 1],
[ 1, 97887, 1],
[ 1, 97944, 100],
[ 1, 97955, 2]])

Or you want to delete matching rows (here using indices is more convenient than masks)

np.delete(a, idx, axis=0)
array([[ 1, 97553, 1],
[ 1, 97587, 1],
[ 1, 97826, 3],
[ 1, 97832, 1],
[ 1, 97839, 1],
[ 1, 97887, 1],
[ 1, 97955, 2]])

Find index of array in multidimensional array by string value

That's returning nil, because there's no element i (index) in the array with value #FFF600 (nor FFF600), you need to access to the hex_value key value:

p [
{:id=>5, :name=>"Leaf Green", :hex_value=>"047115"},
{:id=>15, :name=>"Lemon Yellow", :hex_value=>"FFF600"},
{:id=>16, :name=>"Navy", :hex_value=>"285974"}
].yield_self { |this| this.each_index.select { |index| this[index][:hex_value] == 'FFF600' } }
# [1]

Giving you [1], because of using select, if you want just the first occurrence, you can use find instead.

I'm using yield_self there, to avoid assigning the array to a variable. Which is equivalent to:

array = [
{:id=>5, :name=>"Leaf Green", :hex_value=>"047115"},
{:id=>15, :name=>"Lemon Yellow", :hex_value=>"FFF600"},
{:id=>16, :name=>"Navy", :hex_value=>"285974"}
]
p array.each_index.select { |index| array[index][:hex_value] == 'FFF600' }
# [1]

Being Ruby, you can use the method for that: Enumerable#find_index

p [
{:id=>5, :name=>"Leaf Green", :hex_value=>"047115"},
{:id=>15, :name=>"Lemon Yellow", :hex_value=>"FFF600"},
{:id=>16, :name=>"Navy", :hex_value=>"285974"}
].find_index { |hash| hash[:hex_value] == 'FFF600' }
# 1

How to get the index of an element in an 2D array? [closed]

By converting your 2D Array int[][] to List<List<Integer>>, you can take advantage of indexOf to find the index of your max:

List<List<Integer>> triangle = new ArrayList<List<Integer>>();
triangle.add(Arrays.asList(75));
triangle.add(Arrays.asList(95, 64));

for (List<Integer> row : triangle) {
// you can also ask for row.indexOf(max);
System.out.println("At row: " + triangle.indexOf(row) + " is: " + row.indexOf(64));
}

(F#) Find Index of element in 2D Array

In response to your comment: yes, arrays cannot be matched with head and tail like lists. But they do have indicies! :-)

A recursive function does not have to recurse over the data structure. The recursing path may be defined by something different. For example: why don't we recurse over the array indicies from zero to max (or back)?

let find2D needle (arr: int [,]) = 
let rec go x y =
if y >= arr.GetLength 1 then None
elif x >= arr.GetLength 0 then go 0 (y+1)
elif arr.[x,y] = needle then Some (x,y)
else go (x+1) y
go 0 0

The above solution will scan the array in rows until it finds the needle, at which point it will immediately return.

Alternatively, you can produce yourself a sequence of optional indicies, and then use Seq.tryPick to pick the first element of that sequence that is not None:

let find2D needle (arr: int [,]) = Seq.tryPick id <| seq {
for i in 0..(arr.GetLength 0 - 1) do
for j in 0..(arr.GetLength 1 - 1) do
if arr.[i,j] = needle
then yield Some (i,j)
else yield None
}

Because of how sequences work (they're lazy), this will only iterate until the first Some is found, and then stop. This is slightly more straightforward (as far as readability goes), but also slightly less performant than the plain recursive solution above, because here we incur the overhead of creating and maintaining the sequence.



Related Topics



Leave a reply



Submit