Ноль несколько столбцов в csr_matrix - PullRequest
0 голосов
/ 29 января 2019

Предположим, у меня есть разреженная матрица:

>>> indptr = np.array([0, 2, 3, 6])
>>> indices = np.array([0, 2, 2, 0, 1, 2])
>>> data = np.array([1, 2, 3, 4, 5, 6])
>>> csr_matrix((data, indices, indptr), shape=(3, 3)).toarray()
array([[1, 0, 2],
       [0, 0, 3],
       [4, 5, 6]])

Я хочу обнулить столбцы 0 и 2. Ниже я хочу получить:

array([[0, 0, 0],
       [0, 0, 0],
       [0, 5, 0]])

Ниже я попробовал:

sp_mat = csr_matrix((data, indices, indptr), shape=(3, 3))
zero_cols = np.array([0, 2])
sp_mat[:, zero_cols] = 0

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

SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.

Поскольку у меня большой sp_mat, преобразование в lil_matrix очень медленное.

Что такоеэффективный способ?

1 Ответ

0 голосов
/ 29 января 2019
In [87]: >>> indptr = np.array([0, 2, 3, 6])
    ...: >>> indices = np.array([0, 2, 2, 0, 1, 2])
    ...: >>> data = np.array([1, 2, 3, 4, 5, 6])
    ...: M = sparse.csr_matrix((data, indices, indptr), shape=(3, 3))
In [88]: M
Out[88]: 
<3x3 sparse matrix of type '<class 'numpy.int64'>'
    with 6 stored elements in Compressed Sparse Row format>

Посмотрите, что происходит с присваиванием csr:

In [89]: M[:, [0, 2]] = 0
/usr/local/lib/python3.6/dist-packages/scipy/sparse/compressed.py:746: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
  SparseEfficiencyWarning)
In [90]: M
Out[90]: 
<3x3 sparse matrix of type '<class 'numpy.int64'>'
    with 7 stored elements in Compressed Sparse Row format>
In [91]: M.data
Out[91]: array([0, 0, 0, 0, 0, 5, 0])
In [92]: M.indices
Out[92]: array([0, 2, 0, 2, 0, 1, 2], dtype=int32)

Мало того, что оно дает предупреждение, но оно фактически увеличивает количество «редких» терминов, хотя большинство теперь имеютзначение 0.Они удаляются только при очистке:

In [93]: M.eliminate_zeros()
In [94]: M
Out[94]: 
<3x3 sparse matrix of type '<class 'numpy.int64'>'
    with 1 stored elements in Compressed Sparse Row format>

В индексированном назначении csr не различает установку 0 и другие значения.Он относится ко всем одинаково.

Следует отметить, что предупреждение об эффективности дается в первую очередь, чтобы пользователи не использовали его повторно (как в итерации).Для одноразовых действий это слишком тревожно.

Для индексированного присваивания формат lil более эффективен (или, по крайней мере, не предупреждает об эффективности).Но преобразование в / из этого формата отнимает много времени.

Другой вариант - найти и установить новые 0 напрямую, а затем eliminate_zeros).

Другой вариант - использовать матричное умножение.,Я думаю, что диагональная разреженность с 0 в правильных столбцах поможет.

In [103]: M
Out[103]: 
<3x3 sparse matrix of type '<class 'numpy.int64'>'
    with 6 stored elements in Compressed Sparse Row format>
In [104]: D = sparse.diags([0,1,0], dtype=M.dtype)
In [105]: D
Out[105]: 
<3x3 sparse matrix of type '<class 'numpy.int64'>'
    with 3 stored elements (1 diagonals) in DIAgonal format>
In [106]: D.A
Out[106]: 
array([[0, 0, 0],
       [0, 1, 0],
       [0, 0, 0]])
In [107]: M1 = M*D
In [108]: M1
Out[108]: 
<3x3 sparse matrix of type '<class 'numpy.int64'>'
    with 1 stored elements in Compressed Sparse Row format>
In [110]: M1.A
Out[110]: 
array([[0, 0, 0],
       [0, 0, 0],
       [0, 5, 0]], dtype=int64)

Если вы умножите матрицу на месте, вы не получите предупреждение об эффективности.Он только изменяет значения существующих ненулевых членов, поэтому не меняет разреженность матрицы (по крайней мере, пока вы не удалите нули):

In [111]: M = sparse.csr_matrix((data, indices, indptr), shape=(3, 3))
In [112]: M[:,[0,2]] *= 0
In [113]: M
Out[113]: 
<3x3 sparse matrix of type '<class 'numpy.int64'>'
    with 6 stored elements in Compressed Sparse Row format>
In [114]: M.eliminate_zeros()
In [115]: M
Out[115]: 
<3x3 sparse matrix of type '<class 'numpy.int64'>'
    with 1 stored elements in Compressed Sparse Row format>
...