【问题标题】:Segmentation Fault on ndarray matrices dot productndarray矩阵点积的分割错误
【发布时间】:2014-06-30 11:38:58
【问题描述】:
  • 我正在执行具有 50000 行和 100 列的矩阵的点积及其转置。矩阵的值是浮点数。
A(50000, 100)

B(100, 50000)
  • 基本上我在对较大的稀疏矩阵执行 SVD 后得到矩阵。
  • 矩阵为 numpy.ndarray 类型。
  • 我使用 numpy 的点法将两个矩阵相乘。我得到分段错误。

    numpy.dot(A, B)

点积在 30000 行的矩阵上运行良好,但在 50000 行时失败。

  • numpy 的点积有限制吗?
  • 使用点积时有上述问题吗?
  • 是否有任何其他优秀的 Python 线性代数工具可以在大型矩阵上有效。

【问题讨论】:

  • 我认为不幸的是它会出现段错误而不是给出错误消息。但是,50000x50000 双矩阵需要约 20GB 的内存。你的电脑有多少内存?
  • 在我的盒子上给出一个MemoryError (NumPy 1.8.1)。请注意,float32 格式的结果矩阵将占用 9.3GB,是float64 格式的两倍。
  • @NPE 我在 8GB 机器上运行它。也许这就是 Segmentation Fault 的原因。Python 中有没有有效的方法来处理这些规模的计算?
  • @larsmans 是的.. 内存是问题..
  • @sravan_kumar,你或许可以使用np.memmap数组

标签: python numpy multidimensional-array svd


【解决方案1】:

如您所说,存在内存问题。你想这样做:

numpy.dot(A, A.T)

结果需要大量内存(而不是操作数)。但是,该操作很容易分段执行。您可以使用基于循环的方法一次生成一个输出行:

def trans_multi(A):
    rows = A.shape[0]
    result = numpy.empty((rows, rows), dtype=A.dtype)
    for r in range(rows):
        result[r,:] = numpy.dot(A, A[r,:].T)
    return result

因此,这只是一个较慢且同样消耗内存的版本(numpy.dot 进行了很好的优化)。但是,您最可能想做的是将结果写入文件,因为您没有存储结果的内存:

def trans_multi(A, filename):
    with open(filename, "wb") as f:
        rows = A.shape[0]
        for r in range(rows):
            f.write(numpy.dot(A, A[r,:].T).tostring())

是的,它并不是快如闪电。但是,这很可能是您希望的最快速度。顺序写入通常得到很好的优化。我试过了:

a=numpy.random.random((50000,100)).astype('float32')
trans_multi(a,"/tmp/large.dat")

这大约需要 60 秒,但这确实取决于您的硬盘性能。

为什么不用 memmap?

我喜欢mmap,而numpy.memmap 很棒。但是,numpy.memmap 针对拥有大表并从中计算小结果进行了优化。例如,memmap.dot 针对获取内存映射数组的点积进行了优化。场景是操作数被内存映射,但结果在 RAM 中。恰恰相反,就是这样。

当您进行随机访问时,内存映射非常有用。这里的访问不是随机访问,而是顺序写入。另外,如果您尝试使用numpy.memmap 创建一个 (50000,50000) 的 float32 数组,这将需要一些时间(由于某种原因我不明白,也许它会初始化数据,即使不需要)。

但是,在创建文件之后,使用numpy.memmap 分析大表是一个非常好的主意,因为它提供了最佳的随机读取性能和非常方便的界面。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    相关资源
    最近更新 更多