【问题标题】:Numpy.Cov of a Large Nx3 Array Produces MemoryError大型 Nx3 数组的 Numpy.Cov 产生 MemoryError
【发布时间】:2017-03-03 01:32:44
【问题描述】:

我有一个大小为 Nx3 的大型二维数组。该数组包含 (X,Y,Z) 格式的点云数据。我在虚拟环境中使用 Ubuntu 中的 Python 从 .ply 文件中读取数据。

当我试图找到这个数组的协方差时 rowvar 设置为 True (意味着每一行都被视为一个变量),我得到 MemoryError.

我知道这会创建一个非常大的数组,显然对于我分配的 8 Gb 内存来说太大而无法处理。在不增加内存分配的情况下,是否有解决此问题的不同方法?是否有不同的计算协方差矩阵元素的方法,以免内存过载?

【问题讨论】:

  • N的值是多少?
  • N的值可以大到23000。
  • 请发布您的代码。根据我的经验,8Gb 应该足够了
  • 结果将需要大约 4 Gb 的内存。在计算协方差矩阵之前,你能检查一下实际上有多少内存可用吗?另外,计算完 23000x23000 矩阵后,你打算如何处理它?
  • 您希望结果是什么形状? 3x3 还是 NxN?

标签: python arrays numpy covariance point-clouds


【解决方案1】:

你可以把它切成一个循环,只保留上面的三角形。

import numpy as np

N = 23000
a = np.random.random((N, 3))
c = a - a.mean(axis=-1, keepdims=True)
out = np.empty((N*(N+1) // 2,))
def ravel_triu(i, j, n):
    i, j = np.where(i>j, np.broadcast_arrays(j, i), np.broadcast_arrays(i, j))
    return i*n - i*(i+1) // 2 + j
def unravel_triu(k, n):
    i = n - (0.5 + np.sqrt(n*(n+1) - 2*k - 1)).astype(int)
    return i, k - (i*n - i*(i+1) // 2)
ii, jj = np.ogrid[:N, :N]
for j in range(0, N, 500):
    out[ravel_triu(j, j, N):ravel_triu(min(N, j+500), min(N, j+500), N)] \
        = np.einsum(
            'i...k,...jk->ij', c[j:j+500], c[j:]) [ii[j:j+500] <= jj[:, j:]]

显然,您的协方差将被严重欠采样,并且协方差矩阵高度秩亏...

【讨论】:

  • 为什么会有帮助?你仍然分配了 NxN 矩阵
  • @Eric 它避免了 NxNx3 中间体,它在我的系统上造成了不可行和可行之间的区别。
  • @Eric 我现在明白你的意思了,我真傻。为了节省一点面子,我将其更新为仅使用上三角形。
  • @troymyname00 我已经更新了我的 A,只使用了一半以上的内存。它仅存储上三角形。我已经包含了在 2d 和压缩索引之间转换的便利函数。
  • 所以要确认一下,有没有NxNx3 中间人?我明白为什么会有,但似乎一个明智的实现不会创建一个。
猜你喜欢
  • 2017-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-15
  • 2019-12-13
  • 1970-01-01
相关资源
最近更新 更多