NumPy matrix to SciPy sparse matrix: What is the safest way to add a scalar?

后端 未结 1 566
心在旅途
心在旅途 2021-01-14 19:41

First off, I\'m no mathmatician. I admit that. Yet I still need to understand how ScyPy\'s sparse matrices work arithmetically in order to switch from a dense NumPy matrix t

1条回答
  •  生来不讨喜
    2021-01-14 20:08

    Admittedly sparse matrices aren't really in my wheelhouse, but ISTM the best way forward depends on the matrix type. If you're DOK:

    >>> S = dok_matrix((5,5))
    >>> S[2,3] = 10; S[4,1] = 20
    >>> S.todense()
    matrix([[  0.,   0.,   0.,   0.,   0.],
            [  0.,   0.,   0.,   0.,   0.],
            [  0.,   0.,   0.,  10.,   0.],
            [  0.,   0.,   0.,   0.,   0.],
            [  0.,  20.,   0.,   0.,   0.]])
    

    Then you could update:

    >>> S.update(zip(S.keys(), np.array(S.values()) + 99))
    >>> S
    <5x5 sparse matrix of type ''
        with 2 stored elements in Dictionary Of Keys format>
    >>> S.todense()
    matrix([[   0.,    0.,    0.,    0.,    0.],
            [   0.,    0.,    0.,    0.,    0.],
            [   0.,    0.,    0.,  109.,    0.],
            [   0.,    0.,    0.,    0.,    0.],
            [   0.,  119.,    0.,    0.,    0.]])
    

    Not particularly performant, but is O(nonzero).

    OTOH, if you have something like COO, CSC, or CSR, you can modify the data attribute directly:

    >>> C = S.tocoo()
    >>> C
    <5x5 sparse matrix of type ''
        with 2 stored elements in COOrdinate format>
    >>> C.data
    array([ 119.,  109.])
    >>> C.data += 1000
    >>> C
    <5x5 sparse matrix of type ''
        with 2 stored elements in COOrdinate format>
    >>> C.todense()
    matrix([[    0.,     0.,     0.,     0.,     0.],
            [    0.,     0.,     0.,     0.,     0.],
            [    0.,     0.,     0.,  1109.,     0.],
            [    0.,     0.,     0.,     0.,     0.],
            [    0.,  1119.,     0.,     0.,     0.]])
    

    Note that you're probably going to want to add an additional

    >>> C.eliminate_zeros()
    

    to handle the possibility that you've added a negative number and so there's now a 0 which is actually being recorded. By itself, that should work fine, but the next time you did the C.data += some_number trick, it would add somenumber to that zero you introduced.

    0 讨论(0)
提交回复
热议问题