简体   繁体   中英

How to get “2d indices” of 2d ndarray ordered by value of elements

I have a 2d ndarray of ndarrays, which looks like:

array([[array([0]), array([0, 1]), array([0, 1]), None, None,array([0, 1])],
       [array([0, 1]), None, array([0, 1]), array([0, 1]), array([0, 1]),None],
       [None, None, array([0, 1]), None, None, None],
       [array([0, 1]), array([0, 1]), None, array([0, 1]), array([0, 1]),array([0, 1])],
       [array([0, 1]), None, None, None, array([0, 1]), None],
       [array([0, 1]), None, array([0, 1]), array([0, 1]), array([0, 1]),None]], dtype=object)

My aim is to get the indices of the elements, sorted by the len(element) , also skips those elements which are None . Like:

array([[0,0], --> len= 1
       [0,1], --> len=2
       [0,2], --> len=2
       [0,5],  ...
       [1,0],
       [1,2],
       [1,3],
       [1,4], 
       ...   ])

I have tried to first convert the elements to their len , which will give us something like:

array([[1, 2, 2, 0, 0, 2],
       [2, 0, 2, 2, 2, 0],
       [0, 0, 2, 0, 0, 0],
       [2, 2, 0, 2, 2, 2],
       [2, 0, 0, 0, 2, 0],
       [2, 0, 2, 2, 2, 0]], dtype=object)

However, I couldn't find an effective way to generate the indices list(or ndarray will do).

Please help me with this. I appreciate anyone who could solve this problem or give me some clue.

Edit: I have found a close but not perfect solution: Due to the data constraints, the elements of "lenArray" can only have 3 kinds of values: 1, 2, inf. So I can take advantage of this to do:

ones = np.column_stack(np.where(lenArray==1))
twos = np.column_stack(np.where(lenArray==2))
infs = np.column_stack(np.where(lenArray==inf))
sort_lenidx = np.concatenate((ones,twos,infs))

Where sort_lenidx will match my needs. However, this is not a very general(if the possible value nums be very big, this will be useless) and elegant way to solve my problem. I still hope someone could give me a better way to do it. I will appreciate for your help in any form.

Let's call the array containing lengths lenArray .

The right way of doing this would be by creating another 2d array- rowNcol , that contain the row and column indices of lenArray as elements. Then, implement a sorting algorithm on lenArray and perform identical operations on rowNcol to finally obtain the desired array of indices.

That being said, you could exploit the fact that we know beforehand, the type (int) and range of elements inside lenArray and simply iterate through the possible elements in the following manner:

from numpy import array, amax


lenArray = array([[1, 2, 2, 0, 0, 2],
                  [2, 0, 2, 2, 2, 0],
                  [0, 0, 2, 0, 0, 0],
                  [2, 2, 0, 2, 2, 2],
                  [2, 0, 0, 0, 2, 0],
                  [2, 0, 2, 2, 2, 0]])

rows, cols = lenArray.shape
lenMax = amax(lenArray)

for lenVal in range(lenMax):
    for i in range(rows):
        for j in range(cols):
            if (lenArray[i,j] == lenVal):
                print(str(i) + ',' + str(j))


This is however, extremely inefficient if the size of lenArray is very large, since you are parsing it over and over.

Edit: I later came across numpy.argsort which appears to do exactly what you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM