Получите топ-n элементов каждой строки в scipy разреженной матрице

После прочтения этого аналогичного Вопрос, я до сих пор не могу полностью понять, как приступить к реализации решения, которое я ищу. У меня разреженная матрица, то есть:

 import numpy as np
 from scipy import sparse
 arr = np.array([[0,5,3,0,2],[6,0,4,9,0],[0,0,0,6,8]])
 arr_csc = sparse.csc_matrix(arr)

Я хотел бы эффективно получить верхние n элементов каждой строки без преобразования разреженной матрицы в плотную. Конечный результат должен выглядеть так (при n = 2):

 top_n_arr = np.array([[0,5,3,0,0],[6,0,0,9,0],[0,0,0,6,8]])
 top_n_arr_csc = sparse.csc_matrix(top_n_arr)

person istern    schedule 21.03.2016    source источник


Ответы (1)


Что не так со связанным ответом? В твоем случае это не работает? или ты просто этого не понимаешь? Или это недостаточно эффективно?

Я собирался предложить разработать способ нахождения верхних значений для строки матрицы формата lil и применить эту строку за строкой. Но я бы просто повторил свой предыдущий ответ.


Хорошо, мой предыдущий ответ был началом, но мне не хватало некоторых деталей по итерации через формат lol. Вот начало; это, вероятно, можно было бы очистить.

Сделайте массив и версию lil:

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()

Функция строки из предыдущего ответа:

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

Обходя строки arr_ll, примените эту функцию и замените элементы:

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]])

В формате lil данные хранятся в 2 массивах типов объектов в виде подсписок, один с номерами данных, другой с индексами столбцов.

Просмотр атрибутов данных разреженной матрицы удобен при выполнении новых задач. Изменение этих атрибутов сопряжено с определенным риском, поскольку приводит к повреждению всего массива. Но похоже, что формат lil можно безопасно настроить таким образом.

Формат csr лучше подходит для доступа к строкам, чем csc. Его данные хранятся в 3 массивах: data, indices и indptr. Формат lil эффективно разделяет 2 из этих массивов на подсписки на основе информации в indptr. csr отлично подходит для математики (умножение, сложение и т. Д.), Но не так хорош при изменении разреженности (превращении ненулевых значений в нули).

person hpaulj    schedule 21.03.2016
comment
можно ли попросить вас показать, как вы бы это сделали с помощью lil? Я прочитал ваш подробный ответ, но не смог разобраться. - person istern; 21.03.2016