【问题标题】:Plot heatmap of sparse matrix绘制稀疏矩阵的热图
【发布时间】:2017-07-01 19:47:17
【问题描述】:

我有一个包含直方图的大型稀疏矩阵,我想将其绘制为热图。通常我会简单地绘制完整的矩阵(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)。

【问题讨论】:

  • 我自己从未尝试过,但你有没有看过datashader。可能有用。
  • 您是否考虑过简单地将点单独绘制为散点或矩形集合?
  • 我通常会这样做,但在这种情况下,每个单元格都包含一个计数,所以我不关心单元格是否被填充,而是关心它拥有什么值。我不确定如何使用 scatter 将其可视化。我还没有看过datashader,但应该看看。
  • 在热图中,颜色用于传达有关数据值的信息。通常这是通过使用颜色图来完成的。因此,根据颜色图设置分散或收集项目的颜色可能是一种选择。
  • 我明白你的意思。您知道如何在实践中实施吗?

标签: python matplotlib scipy sparse-matrix heatmap


【解决方案1】:

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

 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

这段代码 sn-p 实现了一个简单的分箱,但可以改进以包含更复杂的过滤器。分箱矩阵只是分箱的 id 矩阵,例如 S_ij = 1 if j // s = i else 0。

更多解释。由于原始矩阵非常大,因此可以对其进行下采样,而输出中没有任何视觉上明显的差异。

问题是如何在不首先创建密集表示的情况下进行下采样。一种可能的答案是用矩阵乘法表示分箱,然后使用稀疏矩阵乘法。

因此,如果将右侧的原始数据与分箱矩阵T 相乘,那么T 的列对应于列分箱,特别是T 的列数将决定下采样的像素数数据将具有 x 方向。 T 的每一列都决定了哪些内容进入相应的 bin,哪些内容不进入。在示例中,我将编码相邻列(原始矩阵的)的一些元素设置为 1,其余为 0。这会将这些列的总和放在它们之间,并将总和放入结果矩阵中,换句话说,它将这些列合并在一起.

从左边乘以完全相同的方式,只是它影响行,而不是列。

如果您觉得分箱过于粗糙,您可以将简单的零一方案替换为平滑内核,例如,只需确保生成的矩阵保持稀疏即可。建立这样一个矩阵需要更多的努力,但并不困难。您正在为数据使用稀疏矩阵,因此我假设您熟悉如何构造稀疏矩阵。

【讨论】:

  • 感谢您的建议。您能否再解释一下这里的采样是如何工作的/我如何更改采样的内容?我担心我还没有完全关注它。
  • 我使用的是 python2.7(很抱歉,这在我的帖子中并不明显),所以 @ 运算符不存在。根据这篇文章(stackoverflow.com/questions/34142485/…),它相当于np.matmul,而不是np.dot。这是你的意图吗?
  • @P-M ugh,你在那里的链接很讨厌。好消息是,只要您使用二维数组 np.dot(a, b)np.matmul(a, b)a @ ba.dot(b) 都会产生相同的结果,所以请自行选择。
  • 是的,也得出了这个结论。我意识到虽然使用np.matmul 不适用于稀疏数组,因为我需要使用适当的scipy 例程(否则为TypeError: Object arrays are not currently supported)所以我使用result = S.dot(data),后跟result = result.dot(T)。我现在正在尝试为st 找到一个合适的值,以给我一个好的形象。
猜你喜欢
  • 2020-10-29
  • 1970-01-01
  • 2014-05-22
  • 2013-04-11
  • 1970-01-01
  • 2018-01-19
  • 2019-10-31
  • 2012-01-10
  • 1970-01-01
相关资源
最近更新 更多