2014-08-28 3 views
2

У меня есть две scipy разреженные матрицы csr с одинаковой формой, но потенциально разные значения данных и значение nnz. Теперь я хочу получить 10 лучших элементов одной матрицы и увеличить значение на тех же показателях на другой матрице. Мой текущий подход заключается в следующем:Показатели scipy sparse csr_matrix

idx = a.data.argpartition(-10)[-10:] 
i, j = matrix.nonzero() 

i_idx = i[idx] 
j_idx = j[idx] 

b[i_idx, j_idx] += 1 

Причина, почему я должен идти по этому пути является то, что a.data и b.data не обязательно иметь одинаковое число элементов и, следовательно, показатели будут отличаться.

Вопрос теперь в том, смогу ли я каким-то образом улучшить это. Насколько я знаю, ненулевая процедура не изящна, поскольку мне приходится выделять два новых массива, и я уже очень жестко отношусь к памяти. Я могу получить j_indices через csr_matrix.indices, но как насчет i_indices? Могу ли я использовать indptr для этого?

Счастливые для любых намеков.

+0

'indptr' имеет одно значение для каждой строки (плюс 1). Он указывает, где каждая строка начинается в массивах 'data' и' index '. Вы можете выполнить математику, или вы можете преобразовать массив 'tocoo()'. Тогда 'row' и' col' имеют значения, которые вы хотите. Но будьте осторожны, есть некоторые предупреждения о том, что индексы не могут быть отсортированы. – hpaulj

+0

Посмотрите на код для 'nonzero'. Если преобразование матрицы в 'coo' и возвращает' row' и 'col'. – hpaulj

+0

«Первые 10 элементов» означают первые 10 ненулевых значений в формате CSR? –

ответ

0

Я не уверен, что означает «верхние 10 элементов». Я предполагаю, что если у вас есть матрицы A и B, вы хотите установить B [i, j] + = 1, если A [i, j] находится в пределах первых 10 ненулевых записей A (в формате CSR). Я также предполагаю, что B [i, j] может быть нулевым, что является наихудшим показателем производительности, поскольку вам нужно изменить структуру разреженности вашей матрицы.

CSR не является идеальным форматом для изменения структуры разреженности. Это связано с тем, что каждая новая вставка/удаление является сложностью O (nnzs) (при условии, что хранилище CSR поддерживается массивом - и обычно это).

Вы можете использовать формат DOK для вашей второй матрицы (той, которую вы изменяете), которая обеспечивает доступ к элементам O (1).

Я не оценил это, но я полагаю, что ваш вариант 10 * O (nnzs) в худшем случае, когда вы добавляете 10 новых ненулевых значений, тогда как для версии DOK должна понадобиться O (nnzs) для построения матрицы, тогда O (1) для каждой вставки и, наконец, O (nnzs), чтобы преобразовать его обратно в CSR (при условии, что это необходимо).

Смежные вопросы