Очевидное индексированное дополнение действительно работает. Это дает предупреждение об эффективности, но это не значит, что это самый медленный путь, просто вы не должны рассчитывать на повторение этого. Он предлагает работать с форматом lil
, но переход на это и обратно, вероятно, занимает больше времени, чем выполнение добавления к матрице csr
.
In [1049]: B.A
Out[1049]:
array([[0, 9, 0, 0, 1, 0],
[2, 0, 5, 0, 0, 9],
[0, 2, 0, 0, 0, 0],
[2, 0, 0, 0, 0, 0],
[0, 9, 5, 3, 0, 7],
[1, 0, 0, 8, 9, 0]], dtype=int32)
In [1051]: B[1,:] += np.array([1,0,1,0,0,0])
/usr/local/lib/python3.5/dist-packages/scipy/sparse/compressed.py:730: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
SparseEfficiencyWarning)
In [1052]: B
Out[1052]:
<6x6 sparse matrix of type '<class 'numpy.int32'>'
with 17 stored elements in Compressed Sparse Row format>
In [1053]: B.A
Out[1053]:
array([[0, 9, 0, 0, 1, 0],
[3, 0, 6, 0, 0, 9],
[0, 2, 0, 0, 0, 0],
[2, 0, 0, 0, 0, 0],
[0, 9, 5, 3, 0, 7],
[1, 0, 0, 8, 9, 0]])
Как показывает связанный вами вопрос, можно действовать непосредственно по атрибутам разреженной матрицы. Его код показывает, почему есть предупреждение об эффективности - в общем случае он должен перестроить атрибуты матрицы.
lil
более эффективен для замены строк, поскольку он просто должен изменить подсписку в матрицах .data
и .rows
атрибутов. Изменение одной строки не изменяет атрибуты любого из других.
Это сказало, если ваша добавка имеет такую же разреженность, что и исходный ряд, то можно изменить отдельные элементы атрибута data
без переделки .indices
или .indptr
. Опираясь на связанный коде
A.data[:idx_start_row : idx_end_row]
является кусочком A.data
, который будет изменен. Конечно, вам нужен соответствующий фрагмент из «вектора».
Начиная с In [1049] B
In [1085]: B.indptr
Out[1085]: array([ 0, 2, 5, 6, 7, 11, 14], dtype=int32)
In [1086]: B.data
Out[1086]: array([9, 1, 2, 5, 9, 2, 2, 9, 5, 3, 7, 1, 8, 9], dtype=int32)
In [1087]: B.indptr[[1,2]] # row 1
Out[1087]: array([2, 5], dtype=int32)
In [1088]: B.data[2:5]
Out[1088]: array([2, 5, 9], dtype=int32)
In [1089]: B.indices[2:5] # row 1 column indices
Out[1089]: array([0, 2, 5], dtype=int32)
In [1090]: B.data[2:5] += np.array([1,2,3])
In [1091]: B.A
Out[1091]:
array([[ 0, 9, 0, 0, 1, 0],
[ 3, 0, 7, 0, 0, 12],
[ 0, 2, 0, 0, 0, 0],
[ 2, 0, 0, 0, 0, 0],
[ 0, 9, 5, 3, 0, 7],
[ 1, 0, 0, 8, 9, 0]], dtype=int32)
Обратите внимание, где измененные значения, [3,7,12], в формате lil
:
In [1092]: B.tolil().data
Out[1092]: array([[9, 1], [3, 7, 12], [2], [2], [9, 5, 3, 7], [1, 8, 9]], dtype=object)
Просьба уточнить ваш вопрос --SO Обзор –
вы имеете в виду не- место? –
На месте. Другой вопрос заключается в добавлении двух CSR-матриц (с теми же размерами). Это основные операции, но я не могу найти правильный способ их выполнения. – beygel