我有一个很大的稀疏矩阵,它包含一个直方图,我想把它画成热图。通常,我只需绘制完整的矩阵(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 ),但是在没有将其转换成密集矩阵的情况下,还没有找到关于如何绘制热图的文章。是否可以这样做呢?(或者有没有其他方法可以在不耗尽内存的情况下绘制它呢?)我的稀疏矩阵目前是丁香矩阵(scipy.sparse.lil_matrix)。
发布于 2017-02-13 18:21:30
一个想法是使用稀疏操作降低样本。
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这个代码片段实现了一个简单的二进制化,但是可以对其进行改进,以包含更复杂的过滤器。binning矩阵只是被绑定的id矩阵,例如,如果j // s=i for 0,则S_ij =1。
再解释一下。由于原始矩阵非常大,因此可以对其进行降采样,而在输出方面没有任何视觉上的差异。
问题是如何在不首先创建密集表示的情况下降低样本。一个可能的答案是用矩阵乘法来表示二进制,然后使用稀疏矩阵乘法。
因此,如果将原始数据从右边乘以一个二进制矩阵T,那么T的列对应于列桶,特别是T列数将决定下采样数据在x方向上有多少像素。T的每一列都决定哪些进入相应的bin,哪些没有。在本例中,我将编码相邻列(原始矩阵)的许多元素设置为1,其余设置为0。这会将这些列的和放在它们之间,并将和放在结果矩阵中,换句话说,它将这些列合并在一起。
从左乘的工作方式完全相同,只是影响行,而不是列。
如果您觉得binning太粗糙,您可以用光滑的内核替换简单的零1方案,只需确保结果矩阵保持稀疏即可。建立这样一个矩阵需要付出更多的努力,但并不困难。您正在为数据使用稀疏矩阵,所以我假设您熟悉如何构造稀疏矩阵。
https://stackoverflow.com/questions/42210594
复制相似问题