scipy 绘制稀疏矩阵的热图

w41d8nur  于 2023-10-20  发布在  其他
关注(0)|答案(2)|浏览(161)

我有一个包含直方图的大型稀疏矩阵,我想将其绘制为热图。通常我会简单地绘制完整的矩阵(h)如下:

import matplotlib.pyplot as plt
plt.imshow(h.T, interpolation="nearest", origin="lower")
plt.colorbar()
plt.savefig("corr.eps")

然而,在这种情况下,我有一个问题,即完整的矩阵将具有189,940x189,940的维度,这对我来说太大了,无法保存在内存中。我已经找到了关于绘制稀疏模式的帖子(例如,python matplotlib plot sparse matrix pattern),但没有关于如何绘制热图,而不将其转换为密集矩阵。有可能这样做吗?(或者有没有其他方法来绘制它而不耗尽RAM?我的稀疏矩阵目前是一个lilmatrix(scipy.sparse.lil_matrix)。

3okqufwl

3okqufwl1#

一个想法是使用稀疏操作进行下采样。

data = data.tocsc()       # sparse operations are more efficient on csc
 N, M = data.shape
 s, t = 400, 400           # decimation factors for y and x directions
 T = sparse.csc_matrix((np.ones((M,)), np.arange(M), np.r_[np.arange(0, M, t), M]), (M, (M-1) // t + 1))
 S = sparse.csr_matrix((np.ones((N,)), np.arange(N), np.r_[np.arange(0, N, s), N]), ((N-1) // s + 1, N))
 result = S @ data @ T     # downsample by binning into s x t rectangles
 result = result.todense() # ready for plotting

这个代码片段实现了一个简单的装箱,但是可以进行改进以包含更复杂的过滤器。装仓矩阵只是装仓的id矩阵,例如,如果j // s = i,则S_ij = 1,否则为0。
更多的解释。由于原始矩阵非常大,因此可以对其进行下采样,而不会在输出中产生任何视觉上的差异。
问题是如何在不首先创建密集表示的情况下进行下采样。一个可能的答案是用矩阵乘法来表示分箱,然后使用稀疏矩阵乘法。
因此,如果将原始数据从右边乘以一个合并矩阵T,那么T的列对应于列仓,特别是T的列数将决定下采样数据在 x 方向上的像素数。T的每一列决定了什么进入相应的bin,什么不进入。在这个例子中,我将编码(原始矩阵的)相邻列的元素数量设置为1,其余的设置为0。这将对这些列进行求和,并将求和结果放入结果矩阵中,换句话说,它将这些列合并在一起。
从左边相乘的方式完全相同,只不过它影响行,而不是列。
如果你觉得合并太粗糙,你可以用一个平滑的内核来代替简单的0 - 1方案,只要确保得到的矩阵保持稀疏即可。建立这样一个矩阵需要更多的努力,但并不困难。您正在为数据使用稀疏矩阵,因此我假设您熟悉如何构造稀疏矩阵。

ejk8hzay

ejk8hzay2#

Paul的方法就是matspy用来制作间谍阴谋的方法。从视觉上看,它看起来像这样:

Matspy只关心稀疏模式,而不关心值,但我们可以使用它的内部helper方法来创建这些左矩阵和右矩阵:

data  # a scipy matrix
binned_shape = tuple(int(x / 3) for x in data.shape)  # example: shrink by a third

from matspy.adapters.scipy_impl import generate_spy_triple_product_coo

left, right = generate_spy_triple_product_coo(data.shape, binned_shape)

result = left @ data @ right
result = result.todense()

相关问题