Get top-n items of every row in a scipy sparse matrix

前端 未结 1 1979
北荒
北荒 2020-12-20 02:44

After reading this similar question, I still can\'t fully understand how to go about implementing the solution im looking for. I have a sparse matrix, i.e.:



        
相关标签:
1条回答
  • 2020-12-20 03:06

    What is wrong with the linked answer? Does it not work in your case? or you just don't understand it? Or it isn't efficient enough?

    I was going to suggest working out a means of finding the top values for a row of an lil format matrix, and apply that row by row. But I would just be repeating my earlier answer.


    OK, my previous answer was a start, but lacked some details on iterating through the lol format. Here's a start; it probably could be cleaned up.

    Make the array, and a lil version:

    In [42]: arr = np.array([[0,5,3,0,2],[6,0,4,9,0],[0,0,0,6,8]])    
    In [43]: arr_sp=sparse.csc_matrix(arr)
    In [44]: arr_ll=arr_sp.tolil()
    

    The row function from the previous answer:

    def max_n(row_data, row_indices, n):
            i = row_data.argsort()[-n:]
            # i = row_data.argpartition(-n)[-n:]
            top_values = row_data[i]
            top_indices = row_indices[i]  # do the sparse indices matter?
            return top_values, top_indices, i
    

    Iterate over the rows of arr_ll, apply this function and replace the elements:

    In [46]: for i in range(arr_ll.shape[0]):
        d,r=max_n(np.array(arr_ll.data[i]),np.array(arr_ll.rows[i]),2)[:2]
        arr_ll.data[i]=d.tolist()
        arr_ll.rows[i]=r.tolist()
       ....:     
    
    In [47]: arr_ll.data
    Out[47]: array([[3, 5], [6, 9], [6, 8]], dtype=object)
    
    In [48]: arr_ll.rows
    Out[48]: array([[2, 1], [0, 3], [3, 4]], dtype=object)
    
    In [49]: arr_ll.tocsc().A
    Out[49]: 
    array([[0, 5, 3, 0, 0],
           [6, 0, 0, 9, 0],
           [0, 0, 0, 6, 8]])
    

    In the lil format, the data is stored in 2 object type arrays, as sublists, one with the data numbers, the other with the column indices.

    Viewing the data attributes of sparse matrix is handy when doing new things. Changing those attributes has some risk, since it mess up the whole array. But it looks like the lil format can be tweaked like this safely.

    The csr format is better for accessing rows than csc. It's data is stored in 3 arrays, data, indices and indptr. The lil format effectively splits 2 of those arrays into sublists based on information in the indptr. csr is great for math (multiplication, addition etc), but not so good when changing the sparsity (turning nonzero values into zeros).

    0 讨论(0)
提交回复
热议问题