-3

I have a 2-d array as below and I would like to know the indices of the non-negative numbers such as an index for 0 will be 1, the index for 1 will be 6 and the index for 8 will be 25. How can I do that?

x=[[0, -1, -1, -1, -1], 
[1, 2, -1, -1, -1], 
[-1, 3, 4, 5, -1], 
[-1, -1, -1, 6, -1], 
[-1, -1, -1, 7, 8]]
Yanirmr
  • 923
  • 8
  • 25
  • 1
    What did you try so far? – Guimoute Feb 11 '20 at 20:56
  • I am clueless right now. I am looking for something to index a 2d array . – abhishek vanamala Feb 11 '20 at 21:05
  • 1
    We typically use 2 numbers to index a 2D list. I'm not sure what you mean by "index for 8 will be 25". Perhaps you want to just flatten the 2D list to a 1D list? – Code-Apprentice Feb 11 '20 at 21:11
  • Take a look at [this question](https://stackoverflow.com/questions/7270321/finding-the-index-of-elements-based-on-a-condition-using-python-list-comprehensi). It doesn't cover your exact problem, but it's a good place to start. – jirassimok Feb 11 '20 at 21:13

5 Answers5

2

Short explanation: You need iterate twice on the 2-D array like that. The first iteration is on the number array and the second iteration (the nested one) is on the numbers of every array. In addition, you need to update the counter that includes the index of the current element. Alternatively, like in your case (and in my code example), all of the arrays are in same length so you mustn't update and counter and you can calculate every element by his index and his array index.

This code will do the work for you:

def non_neg_indices(num_list):
    for arr_index, arr in enumerate(num_list): 
        for ele_index, ele in enumerate(arr):
            if (ele >= 0):
                print (arr_index*len(arr) + ele_index,ele) 

enumerate helps you to work with the indices.

For your input:

x=[[0, -1, -1, -1, -1], 
[1, 2, -1, -1, -1], 
[-1, 3, 4, 5, -1], 
[-1, -1, -1, 6, -1], 
[-1, -1, -1, 7, 8]]     

Execute:

non_neg_indices(x)

The output will be:

0 0
5 1
6 2
11 3
12 4
13 5
18 6
23 7
24 8
Yanirmr
  • 923
  • 8
  • 25
1

Here is the pythonic way to do it.

x=[[0, -1, -1, -1, -1], 
[1, 2, -1, -1, -1], 
[-1, 3, 4, 5, -1], 
[-1, -1, -1, 6, -1], 
[-1, -1, -1, 7, 8]]
indexes = [(i+1)*(j+1) for i, row in enumerate(x) for j,value in enumerate(row) if value >= 0]
print(indexes)
Umar Hayat
  • 4,300
  • 1
  • 12
  • 27
0

You can flatten the list and then use enumerate to get the index like this:

x=[[0, -1, -1, -1, -1], 
[1, 2, -1, -1, -1], 
[-1, 3, 4, 5, -1], 
[-1, -1, -1, 6, -1], 
[-1, -1, -1, 7, 8]]

c = []
for row in x:
    c.extend(row)

indexes = [(i+1, value) for i, value in enumerate(c) if value >= 0]
print(indexes)

>>> [(1, 0), (6, 1), (7, 2), (12, 3), (13, 4), (14, 5), (19, 6), (24, 7), (25, 8)]

marcos
  • 4,473
  • 1
  • 10
  • 24
0

You could try the following where n is the element you are looking for. I am assuming from your example that these are distinct elements.

def indexOf(n, array_2d):
    idx = 0
    for arr in array_2d:
        for element in arr:
            idx += 1 
            if element == n:
                return idx

print(indexOf(0,x)) # output = 1
print(indexOf(1,x)) # output = 6
print(indexOf(8,x)) # output = 25
jws1
  • 111
  • 1
  • 4
0

From my understanding of the question, you are looking for the position of the values which fullfil your condition (x>=0). Not as a nested lists but as a flat list (the index for 8 would be [4][4]). In that case, I would flatten the list as following:

flags = [1 if item>=0 else 0 for sublist in x for item in sublist]
result = [i+1 for i, flag in enumerate(flags) if flag==1]

This result doesn't allow you to get the values where the condition is met. for example x[result[-1]] would raise an exception because 25 is not an index for your list of lists.

Any way, for a comparison like this, in a larger scale, I highly recommend using pandas like this:

import pandas as pd
df = pd.DataFrame(x)
df[df>=0].index

This would return the proper index for latter use on the pandas dataframe (or numpy array).

Harald Heitmann
  • 129
  • 2
  • 10