12

CSR 形式のマトリックスがあるとします。行 (または行) をゼロに設定する最も効率的な方法は何ですか?

次のコードは非常にゆっくりと実行されます。

A = A.tolil()
A[indices, :] = 0
A = A.tocsr()

scipy.sparse.lil_matrixCSR 形式は派手なインデックス作成もスライスへの値の設定もサポートしていないように見えるため、変換する必要がありました。

4

4 に答える 4

10

scipy はそれを実装していないと思いますが、CSR 形式はこれを非常によくサポートしますindptr

# A.indptr is an array, one for each row (+1 for the nnz):

def csr_row_set_nz_to_val(csr, row, value=0):
    """Set all nonzero elements (elements currently in the sparsity pattern)
    to the given value. Useful to set to 0 mostly.
    """
    if not isinstance(csr, scipy.sparse.csr_matrix):
        raise ValueError('Matrix given must be of CSR format.')
    csr.data[csr.indptr[row]:csr.indptr[row+1]] = value

# Now you can just do:
for row in indices:
    csr_row_set_nz_to_val(A, row, 0)

# And to remove zeros from the sparsity pattern:
A.eliminate_zeros()

もちろん、これにより、別の場所から設定された 0 がeliminate_zerosスパース パターンから削除されます。(この時点で)それをしたい場合は、実際に何をしているかによって異なります。新しいゼロを追加する可能性のある他のすべての計算が完了するまで、削除を遅らせることは理にかなっています。または、場合によっては、後で再度変更したい値が 0 になる可能性があるため、それらを削除するのは非常に悪いことです!

eliminate_zerosもちろん、原則としてandを短絡することもできpruneますが、それは非常に手間がかかり、さらに遅くなる可能性があります (C では実行しないため)。


eliminiate_zeros (およびプルーニング) に関する詳細

スパース行列は、一般にゼロ要素を保存しませんが、ゼロ以外の要素がどこにあるかを保存するだけです (大まかに、さまざまな方法で)。eliminate_zerosスパース パターンから行列内のすべてのゼロを削除します (つまり、値が格納される前に、その位置に格納された値はありません、0 でした)。後で 0 を別の値に変更したい場合、削除は良くありません。そうでない場合は、スペースを節約できます。

Prune は、保存されているデータ配列が必要以上に長い場合、それらを縮小するだけです。A.prune()私が最初にそこに持っていた間、A.eliminiate_zeros()すでにプルーンが含まれていることに注意してください。

于 2012-08-26T12:54:45.113 に答える