scipy.sparse には内部データ構造の違いにより多くの疎行列がある。ただ、マトリックス自体の準備には lil または dok を用い、その後 tocsr などして計算効率の高いフォーマットに変換することが勧められている。
他方、マトリックスの準備にあたって、複数のエレメントに同一の処理を施したい場合がある。疎行列は巨大なデータを扱う場合に用いるしPython なので可能な限りループはしたくない。そこでスライスやリストを用いた処理をしたいのだが lil と dok では挙動に違いがあるようだ。
代入に関してはスライス、リストによる要素指定が csr,lil,dok など共通して動作する。
他方、要素に対するブロードキャスト演算は dok のみで動作するようだ。
検証コード (たまたま複素行列演算を検証していたため複素数になっている)
from scipy.sparse import csr_matrix,lil_matrix,dok_matrix,dok_matrix
import numpy as np
csr = csr_matrix((10,10),dtype= np.csingle)
lil = lil_matrix((10,10),dtype= np.csingle)
dok = dok_matrix((10,10),dtype= np.csingle)
csr[1,2:4] = 1-1j
csr[2,[7,8,9]] = 1+1j
lil[1,2:4] = 1-1j
lil[2,[7,8,9]] = 1+1j
dok[1,2:4] = 1-1j
dok[2,[7,8,9]] = 1+1j
#ここまでは問題なく動作
csr[1,2:4] += 1-1j
csr[2,[7,8,9]] += 1+1j
lil[1,2:4] += 1-1j
lil[2,[7,8,9]] += 1+1j
dok[1,2:4] += 1-1j
dok[2,[7,8,9]] += 1+1j
#上記は、dok 意外をコメントアウトすると動作。動作しない場合のエラーメッセージは
# NotImplementedError: adding a nonzero scalar to a sparse matrix is not supported
print(type(csr),csr)
print(type(lil),lil)
print(type(dok),dok)