【发布时间】:2021-04-10 06:38:12
【问题描述】:
我有一个稀疏的三角矩阵(例如距离矩阵)。实际上,这将是一个 > 1M x 1M 的距离矩阵,具有高稀疏性。
from scipy.sparse import csr_matrix
X = csr_matrix([
[1, 2, 3, 3, 1],
[0, 1, 3, 3, 2],
[0, 0, 1, 1, 3],
[0, 0, 0, 1, 3],
[0, 0, 0, 0, 1],
])
我想将此矩阵子集化为另一个三角距离矩阵。 索引的顺序可能不同和/或重复。
idx = np.matrix([1,2,4,2])
X2 = X[idx.T, idx]
这可能会导致生成的矩阵不是三角形的,其中一些值缺失 上三角形,一些值在下三角形中重复。
>>> X2.toarray()
array([[1, 3, 2, 3],
[0, 1, 3, 1],
[0, 0, 1, 0],
[0, 1, 3, 1]])
如何才能尽可能高效地得到正确的上三角矩阵? 目前,我在子集之前镜像矩阵,然后将其子集到三角形,但这感觉不是特别有效,因为它至少需要复制所有条目。
# use transpose method, see https://stackoverflow.com/a/58806735/2340703
X = X + X.T - scipy.sparse.diags(X.diagonal())
X2 = X[idx.T, idx]
X2 = scipy.sparse.triu(X2, k=0, format="csr")
>>> X2.toarray()
array([[1., 3., 2., 3.],
[0., 1., 3., 1.],
[0., 0., 1., 3.],
[0., 0., 0., 1.]])
【问题讨论】:
-
澄清一下 - 您正在采样回与原始距离矩阵相同的大小,或者您正在将子集设置为更小的大小?
-
没有明显变小。由于重复的元素,有时甚至更大。
-
我不确定它是否会有所帮助,但
scipy.csr在进行这样的索引时实际上会创建一个extractor矩阵,并通过矩阵乘法得到结果。 -
明确一点,
X2是您数据的有效表示,对吧?您只是使用triu来节省内存?看看sparse.triu做了什么也可能会有所帮助。它将布尔掩码应用于coo数组属性,创建一个新的coo数组,没有较低的tri 值。 -
我会考虑将其实现为与pdist 相同的样式的压缩距离矩阵,但作为 1xN CSR 矩阵,然后在需要获取特定值时使用坐标数学重新索引它.不过,这更像是一个 XY 解决方案。我只是不认为有一个很好的方法来做你要求做的具体事情。
标签: python numpy scipy sparse-matrix