@ Eric Yu` использует плотный массив NumPy:
In [239]: A=np.array([[1,2,3],[3,4,5],[5,6,7]])
In [240]: A
Out[240]:
array([[1, 2, 3],
[3, 4, 5],
[5, 6, 7]])
In [241]: v=[0,1]
при этом индексировании выбираются строки:
In [242]: A[v]
Out[242]:
array([[1, 2, 3],
[3, 4, 5]])
, а из этих столбцов выбираются:
In [243]: A[v][:,v]
Out[243]:
array([[1, 2],
[3, 4]])
Но A[v]
является копией, а не представлением, поэтому присвоение завершится неудачей:
In [244]: A[v][:,v] = 0
In [245]: A
Out[245]:
array([[1, 2, 3],
[3, 4, 5],
[5, 6, 7]])
===
Чтобы правильно проиндексировать блок массива, используйте ix_
(или эквивалент) для создания индексных массивов, которые передаются друг против друга для определения блока:
In [247]: np.ix_(v,v)
Out[247]:
(array([[0],
[1]]), array([[0, 1]]))
In [248]: A[np.ix_(v,v)]
Out[248]:
array([[1, 2],
[3, 4]])
In [249]: A[np.ix_(v,v)]=0
In [250]: A
Out[250]:
array([[0, 0, 3],
[0, 0, 5],
[5, 6, 7]])
Без преобразования ix_
, индексирование с помощью [v,v]
выбирает диагональ:
In [251]: A[v,v]
Out[251]: array([0, 0])
MATLAB M(v,v)
индексирует блок.Индексация диагонали с другой стороны требует использования sub2idx
(или что-то в этом роде).Это тот случай, когда индексная запись MATLAB упрощает одну задачу, а другую - более сложную.numpy
делает наоборот.
===
То, что я написал, применимо и к разреженным матрицам
In [253]: M=sparse.lil_matrix(np.array([[1,2,3],[3,4,5],[5,6,7]]))
In [254]: M
Out[254]:
<3x3 sparse matrix of type '<class 'numpy.int64'>'
with 9 stored elements in LInked List format>
Диагональный выбор:
In [255]: M[v,v]
Out[255]:
<1x2 sparse matrix of type '<class 'numpy.int64'>'
with 2 stored elements in LInked List format>
In [256]: _.A
Out[256]: array([[1, 4]], dtype=int64)
Обратите внимание, что эта матрица (1,2), все еще 2d, в стиле матриц MATLAB.
выбор блока:
In [258]: M[np.ix_(v,v)]
Out[258]:
<2x2 sparse matrix of type '<class 'numpy.int64'>'
with 4 stored elements in LInked List format>
In [259]: _.A
Out[259]:
array([[1, 2],
[3, 4]], dtype=int64)
In [260]: M[np.ix_(v,v)]=0
In [261]: M.A
Out[261]:
array([[0, 0, 3],
[0, 0, 5],
[5, 6, 7]], dtype=int64)
sparse.csr_matrix
будет индексироваться втаким же образом (с некоторыми отличиями в шаге назначения).