Индексирование разреженных матриц является сложным, с рядом переменных, которые могут влиять на время. Ваш тестовый пример является симметричным, поэтому форматы csr
и csc
будут практически одинаковыми. Вещи могут отличаться, если форма прямоугольная или макет другой.
Кроме того, индексирование со скаляром по сравнению со срезом по сравнению со списком может отличаться.
Имейте в виду, что разреженная индексация, независимо от формата, намного медленнее, чем numpy.ndarray
. Старайтесь не использовать разреженный, если вам нужно повторить. (И если вам нужно выполнить итерацию, рассмотрите возможность непосредственной работы с «необработанными» разреженными атрибутами.)
In [64]: d = sparse.diags([-1, 1, 1], [-1, 0, 1], shape= (100, 100))
In [65]: d
Out[65]:
<100x100 sparse matrix of type '<class 'numpy.float64'>'
with 298 stored elements (3 diagonals) in DIAgonal format>
In [66]: %timeit d.tocsr()[:,1]
422 µs ± 13.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [67]: %timeit d.tocsc()[:,1]
506 µs ± 5.89 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [68]: %timeit d.tocsc()[1,:]
506 µs ± 1.15 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Отделить преобразование от индексации:
In [69]: %%timeit x=d.tocsr()
...: x[:,1]
121 µs ± 2.05 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [70]: %%timeit x=d.tocsr()
...: x[1,:]
118 µs ± 2.95 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [71]: %%timeit x=d.tocsc()
...: x[:,1]
290 µs ± 5.89 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [72]: %%timeit x=d.tocsc()
...: x[1,:]
297 µs ± 14.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Я немного удивлен, что csr
время постоянно быстрее. Но только немного. csc
и csr
используют общий базовый класс compressed
(sparse.compressed._cs_matrix
), но детали кодирования, кажется, предпочтительнее csr
.
===
И просто для удовольствия, индексируйте lil
формат
In [73]: %%timeit x=d.tolil()
...: x[1,:]
76.4 µs ± 231 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [74]: %%timeit x=d.tolil()
...: x[:,1]
118 µs ± 647 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Как и ожидалось от хранилища lil
, индексирование строк выполняется быстрее, хотя время индексации столбцов неплохое.
lil
имеет getrow
, который ближе всего в sparse
к numpy
представлению:
In [75]: %%timeit x=d.tolil()
...: x.getrow(1)
36.7 µs ± 233 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
===
Плотная индексация массива, даже если время преобразования быстрее:
In [83]: %%timeit x=d.A
...: x[:,1]
277 ns ± 9.97 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [84]: timeit d.A[:,1]
197 µs ± 587 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)