python - 从 SciPy 稀疏矩阵获取左、右、上、下非零邻居
问题描述
假设我有一个 2D SciPy 稀疏矩阵:
import numpy as np
from scipy.sparse import csc_matrix
arr = np.array([[0, 0, 1, 0, 1],
[1, 0, 0, 1, 0],
[0, 1, 1, 0, 0],
[1, 0, 0, 1, 0],
[0, 1, 0, 0, 0],
])
csc = csc_matrix(arr)
对于矩阵中的每个非零元素,我想创建四个新的稀疏矩阵,其中包含与下一个最近的 Left、Right、Up 和 Down 非零邻居对应的索引。末端的元素可以有环绕的邻居(想想水平和垂直方向的圆形双向链表或环形)。如果一个元素是其行/列中唯一的非零元素,则相应的索引将指向它自己。此外,由于索引可以具有零值(当引用第一行或第一列时)并且与自然为零的元素无法区分,我们将这些零索引设置为 -1 以消除实际索引与零元素的歧义。
对于上面的矩阵,密集的左矩阵和下矩阵如下所示:
left = np.array([[0, 0, 4, 0, 2],
[3, 0, 0, -1, 0],
[0, 2, 1, 0, 0],
[3, 0, 0, -1, 0],
[0, 1, 0, 0, 0],
])
down = np.array([[0, 0, 2, 0, -1],
[3, 0, 0, 3, 0],
[0, 4, -1, 0, 0],
[1, 0, 0, 1, 0],
[0, 2, 0, 0, 0],
])
请记住,索引值为 -1 的元素实际上是对索引零的引用。当然,我需要将这些矩阵设为稀疏矩阵形式,因为我的真实矩阵太大且太稀疏,无法放入内存。
解决方案
这是一种可能的方法来做左边的邻居。它不是特别有效,但如果整个矩阵中没有很多非零条目,它可能工作得很好。您可以通过获取每行的非零条目并且只计算j[i==row]
一次来稍微优化它。
请注意,我只是将索引上移一,而不是设置0
为-1
.
i,j = csc.nonzero()
ind = sp.sparse.csc_matrix(csc.shape,dtype='int')
for row in range(csc.shape[0]):
ind[row,j[i==row]] = np.roll(j[i==row]+1,1)
ind.A = array([[0, 0, 5, 0, 3],
[4, 0, 0, 1, 0],
[0, 3, 2, 0, 0],
[4, 0, 0, 1, 0],
[0, 2, 0, 0, 0]])
推荐阅读
- powershell - “Select -skip”不会跳过第一行
- javascript - NGRX:创建多个reducer 响应的“全局”操作的正确方法是什么?
- c# - WPF:使用 MVVM 的 SelectAll \ UnSelectAll
- mysql - MySQL使用while循环插入多行函数
- opencv - 使用opencv进行外在矩阵计算
- r - 如何在get函数中定义一个序列?
- typo3 - TYPO3 v9:如何查询额外的外部数据库(MSSQL)
- python - Flask / SQLAlchemy - 请求具有多对多关系的表
- javascript - 一种解析 tmTheme 文件以获取设置的方法?
- java - 在 Java android studio 中解析 json