)や各種処理(連結や保存など)を行う方法について、以下の内容を説明する。load_npz()疎行列の基本については以下の記事を参照。以下の説明内容およびサンプルコードはSciPy1.3.1のもの。バージョンが違うと異なる場合があるので注意。(scipy.sparse)同士csr_matrixを例とする。分かりやすいようにtoarray()でNumPy配列ndarrayに変換して出力する。+、-は要素ごとの足し算・引き算となる。結果も同じくcsr_matrix。scipy_sparse_arithmetic_operations.py*は行列積。要素ごとの掛け算はmultiply()メソッドを使う。dot()で明示的に行列積を表すことも可能。scipy_sparse_arithmetic_operations.py/は要素ごとの割り算。0で割られた要素はnanとなり、結果はnumpy.matrixとなる。numpy.matrixは行列(二次元配列)に特化した型。scipy_sparse_arithmetic_operations.pyすべての要素が非ゼロ要素でも変わらずnumpy.matrixが返される。scipy_sparse_arithmetic_operations.py0の要素が無くなってしまい非効率であるため、スカラー値との足し算・引き算はサポートされていない。すべての要素が非ゼロ要素でも同様。scipy_sparse_arithmetic_operations.pyスカラー値との掛け算、割り算はOK。scipy_sparse_arithmetic_operations.pyべき乗は行列積の繰り返しとなる。正の整数のみ指定可能。scipy_sparse_arithmetic_operations.py疎行列の演算は結果のクラスに注意。csr_matrixとcsc_matrixとの演算の結果のクラスは順番によって異なる。lil_matrixは自動的にcsr_matrixに変換される。scipy_sparse_arithmetic_operations.pyなお、処理速度はcsr_matrix同士、または、csc_matrix同士が高速。異なるクラスを混在させたままにするよりもどちらかに統一して処理したほうがよい。NumPy配列ndarrayとの計算あまり使い所はなさそうだが、scipy.sparseとnumpy.ndarrayとの四則演算も可能。-の結果はnumpy.matrix。sparceの順番だとエラーとなる。ndarrayの順番だとエラーにはならないが警告が出る。0の要素はnanとなる。結果はnumpy.matrix。scipy_sparse_arithmetic_operations.py*は行列積となり、結果はnumpy.ndarray。scipy_sparse_arithmetic_operations.py公式ドキュメントにあるように、NumPy1.7時点で、numpy.ndarrayのメソッドdot()やnumpy.dot()の引数にscipy.sparse行列を指定するとおかしな結果となるので注意。scipy_sparse_arithmetic_operations.py要素ごとの掛け算はscipy.sparse行列のmultiply()メソッドを使う。結果はcoo_matrix。こちらもnumpy.multiply()だとうまくいかない。scipy.sparse.linalgscipy.sparse行列(疎行列)の逆行列や固有値などを算出するにはサブモジュールscipy.sparse.linalgの関数を使う。algebra)の意。高度な処理が多く提供されている。Guidenumpy.ndarrayの逆行列や固有値の算出については以下の記事を参照。inv()逆行列はinv()。Guidecsc_matrix以外を引数に指定すると、csc_matrixを使わないと非効率だという警告SparseEfficiencyWarningが出る。ここではコメントアウトしているが、エラーではなく警告なので実行することは可能。scipy_sparse_linalg.pyなお、便宜上、例で使っている行列は0を含まないもの。実際はわざわざscipy.sparseを使うメリットはない。eigs()先にnumpy.linalg.eig()の結果を示す。固有値と固有ベクトルが返される。scipy_sparse_linalg.pyscipy.sparse.linalgの固有値を算出する関数はeigs()。Guideeigs()で得られるのは1組の固有値と固有ベクトルのみ。1(Nは行数)という制約がある。公式ドキュメントにあるように、すべての固有値・固有ベクトルを算出することはできない。Guidekに大きい値を指定するとエラーとなる。scipy_sparse_linalg.py小さいサイズの行列のすべての固有値と固有ベクトルを求めるような用途にはnumpy.linalg.eig()やscipy.linalg.eig()を使うべきで、scipy.sparse.linalg.eigs()は巨大な疎行列向け、ということだと思われる。scipy.sparse.linalg.eigs()の第一引数に指定する行列のデータ型dtypeはfloatである必要がある。整数intだとエラー。scipy_sparse_linalg.pyscipy.sparseのクラスのメソッドcsr_matrixやlil_matrixなどのscipy.sparseのクラスのメソッドをいくつか紹介する。共通の基底クラスspmatrixで定義されているメソッドはどのクラスでも使える。Guide一方、各クラスで独自に定義されているものは別のクラスでは使えない。以下、適宜注記するが、AttributeErrorが出た場合などは公式ドキュメントを参照されたい。numpy.ndarrayと同様に、平均mean()、合計sum()、最大値max()、最小値mean()を算出できる。mean()はlil_matrixなどでは定義されていない。coo_matrixなどで定義されている。lil_matrixなどにはない。scipy_sparse_method.pycos()がないのは0が1になってしまうからだと思われる。coo_matrixなどではdata属性(numpy.ndarray)を処理して上書きすればよい。ここでは元の行列を保持するためcopy()でコピーした行列を処理している。scipy_sparse_method.pycos()に限らず、要素に対して一括で任意の処理を適用できる。scipy_sparse_method.py例えばlil_matrixの場合はdata属性がリストを要素とするnumpy.ndarrayなので一括処理するのは面倒。nonzero()非ゼロ要素の位置を取得するにはnonzero()を使う。行・列のインデックスのリストが返される。scipy_sparse_method.py非ゼロ要素の個数はcount_nonzero()、行列が保持しているデータ数はnnz属性で取得できる。scipy_sparse_method.py例えばcsr_matrixではある要素の値を0としたときに値0の要素としてデータが残るので、count_nonzero()とnnzの値が一致しなくなる。scipy_sparse_method.py一方、lil_matrixでは0にした要素は削除されるのでcount_nonzero()とnnzの値は一致する。種類によって振る舞いが異なるので注意。scipy_sparse_method.pyscipy.sparseの関数scipy.sparse内にいくつか関数が定義されている。数は多くないのでscipy.sparse行列を頻繁に使うなら一度目を通しておくといいだろう。Guideいくつか紹介する。vstack()scipy.sparse行列を連結するのがhstack()(横)、vstack()(縦)。返り値のクラスは、デフォルトでは適切なものが選択される。引数formatに文字列で指定可能。scipy_sparse_hstack_vstack.pyvstack()でも同様。scipy_sparse_hstack_vstack.py行・列をスライスなどで取り出して連結することも可能。hstack()では行数、vstack()では列数が一致していないとエラーになる。tril()上三角行列をtriu()、下三角行列をtril()で取得できる。vstack()と同様に引数formatを指定可能。scipy_sparse_triu_tril.py例の通り、デフォルトでは主対角線を含む上側。引数kで対角線の位置を移動できる。正が上側(右側)、負が下側(左側)。scipy_sparse_triu_tril.pytril()でも同様。load_npz()はnpz形式でそのまま保存・読み込みできる。npz)で保存csr_matrixやcsc_matrixなどの形式がそのまま保存される。dia_matrix。lil_matrixなどはエラーになる。scipy_sparse_save_load_npz.py対応していない形式を保存したい場合はtocsr()などで対応している形式に変換すればOK。npzファイルは複数のnumpy.ndarrayをまとめたもの。scipy.sparse行列のnpzファイルの中身は以下のようになっている。確認する意味はないが参考まで。