Нарезка разреженных матриц в Scipy - Какие типы работают лучше всего?

Учебник SciPy Sparse Matrix очень хорош, но на самом деле он выходит из раздела, посвященного разрезанию un (der), разработанному (все еще в виде контура) - см. раздел: "Обработка разреженных матриц" ).

Я попытаюсь обновить учебник, после ответа на этот вопрос.

У меня большая разреженная матрица - в настоящее время в формате dok_matrix.

import numpy as np
from scipy import sparse
M = sparse.dok_matrix((10**6, 10**6))

Для разных методов я хочу иметь возможность разрезать столбцы, а для других - срезать строки. В идеале я бы использовал расширенную индексацию (т.е. Логический вектор, bool_vect), с помощью которого разрезать разреженную матрицу M - как в:

bool_vect = np.arange(10**6)%2  # every even index
out = M[bool_vect,:]            # Want to select every even row

или

out = M[:,bool_vect] # Want to select every even column

Во-первых, dok_matrices не поддерживают это, но я думаю, что он работает (медленно), если я сначала передаю lil_matrices, через sparse.lil_matrix(M)

Насколько я могу собрать из учебника - для среза столбцов я хочу использовать CSC и срезать строки, я хочу обрезать CSR. Значит, это означает, что я должен отливать матрицу M с помощью:

M.tocsc()[:,bool_vect]

или

M.tocsr()[bool_vect,:]

Я догадываюсь здесь, и мой код медленный из-за этого. Любая помощь от кого-то, кто понимает, как это работает, будет оценена по достоинству. Спасибо заранее.

Если окажется, что я не должен индексировать мою матрицу с булевым массивом, а скорее список целых чисел (индексов) - это тоже то, что я с удовольствием узнаю. Какой бы ни был эффективнее.

Наконец - это большая матрица, поэтому бонусные очки, если это может произойти на месте/с трансляцией.

Ответы

Ответ 1

Хорошо, поэтому я уверен, что "правильный" способ сделать это: если вы нарезаете столбцы, используйте tocsc() и срез, используя список/массив целых чисел. Булевы векторы, похоже, не делают трюк с разреженными матрицами - как это происходит с ndarrays в numpy. Это означает, что ответ есть.

indices = np.where(bool_vect)[0]
out1 = M.tocsc()[:,indices]
out2 = M.tocsr()[indices,:]

Но вопрос: это лучший способ? Это на месте?

На практике это, похоже, происходит на месте - и это намного быстрее, чем предыдущие попытки (используя lil_matrix).