2016-11-21 3 views
0

Я хочу поместить столбец из одной разреженной столбчатой ​​матрицы в другую (пустую) разреженную столбчатую матрицу. игрушки Код:Помещение столбца в пустую разреженную матрицу

import numpy as np 
import scipy.sparse 
row = np.array([0, 2, 0, 1, 2]) 
col = np.array([0, 0, 2, 2, 2]) 
data = np.array([1, 2, 4, 5, 6]) 
M=scipy.sparse.csc_matrix((data, (row, col)), shape=(3, 3)) 
E=scipy.sparse.csc_matrix((3, 3)) #empty 3x3 sparse matrix 

E[:,1]=M[:,0] 

Однако я получаю предупреждение:

SparseEfficiencyWarning: Изменение разреженности структуры csc_matrix является> дорого. lil_matrix более эффективен.

Это предупреждение заставляет меня опасаться, что в процессе матрица преобразуется в другой формат, а затем обратно в csc, что неэффективно. Может ли кто-нибудь подтвердить это и иметь решение?

ответ

0

Предупреждение сообщает вам, что процесс установки новых значений в матрице формата csc (или csr) является сложным. Эти форматы не предназначены для таких простых изменений. Формат lil предназначен для быстрого и легкого изменения такого типа, особенно для внесения изменений в одну строку.

Обратите внимание, что формат coo даже не реализует такой тип индексации.

Это не преобразование в lil и обратно, но это может быть на самом деле быстрее. Мы должны были бы провести несколько тестов времени.

In [679]: %%timeit E=sparse.csr_matrix((3,3)) 
    ...: E[:,1] = M[:,0] 
    ...: 
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py:730: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient. 
    SparseEfficiencyWarning) 
1000 loops, best of 3: 845 µs per loop 
In [680]: %%timeit E=sparse.csr_matrix((3,3)) 
    ...: E1=E.tolil() 
    ...: E1[:,1] = M[:,0] 
    ...: E=E1.tocsc() 
    ...: 
The slowest run took 4.22 times longer than the fastest. This could mean that an intermediate result is being cached. 
1000 loops, best of 3: 1.42 ms per loop 

In [682]: %%timeit E=sparse.lil_matrix((3,3)) 
    ...: E[:,1] = M[:,0] 
    ...: 
1000 loops, best of 3: 804 µs per loop 
In [683]: %%timeit E=sparse.lil_matrix((3,3));M1=M.tolil() 
    ...: E[:,1] = M1[:,0] 
    ...: 
    ...: 
1000 loops, best of 3: 470 µs per loop 

In [688]: timeit M1=M.tolil() 
The slowest run took 4.10 times longer than the fastest. This could mean that an intermediate result is being cached. 
1000 loops, best of 3: 248 µs per loop 

Обратите внимание, что делает назначение с lil (с обеих сторон) является 2 раза быстрее, чем делать это с csc. Но конвертация в/из lil занимает много времени.

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

=================

Настройка строк v столбцов не имеет большого значения.

In [835]: %%timeit E=sparse.csc_matrix((3,3)) 
    ...: E[:,1]=M[:,0] 
    SparseEfficiencyWarning) 
1000 loops, best of 3: 1.89 ms per loop 

In [836]: %%timeit E=sparse.csc_matrix((3,3)) 
    ...: E[1,:]=M[0,:]  
    SparseEfficiencyWarning) 
1000 loops, best of 3: 1.91 ms per loop 
+0

Спасибо за ответ, но обычно формат csc должен быть оптимальным для такой операции нарезания столбцов нет? Я не понимаю, почему это изменило бы структуру разреженности внутри этой конкретной операции. –

+1

Если она меняет количество ненулевых значений, это изменяет разреженность. Это не проблема 'csc' v' csr'. В моих таймингах неважно, копировал ли я строку или столбец. Но не стесняйтесь делать собственные тайминги. – hpaulj

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