高效数组拼接

5

我正在尝试连接几百个大小总计约25GB的数组。我在56GB的机器上进行测试,但是收到了内存错误。我认为我的处理方式效率低下且占用大量内存。这是我的代码:

    for dirname, dirnames, filenames in os.walk('/home/extra/AllData'): 
        filenames.sort()
    BigArray=numpy.zeros((1,200))
    for file in filenames:
        newArray[load(filenames[filea])
        BigArray=numpy.concatenate((BigArrat,newArray))

有什么想法、思路或解决方案吗?

谢谢


@sashkello,我确实需要将它存储在内存中,因为我的应用程序是实时运行的。 - Adham Ghazali
3
它实时运行并不意味着您始终需要全部25GB数据。我可能是错的,也许您手头有一个非常特殊的情况,但我强烈感觉这是一种糟糕的程序设计选择,您需要重新设计它,而不是试图适应如此庞大的数据量。我建议在您的问题中添加有关您特定情况的详细信息,否则除了“不要这样做”之外,真的没有好的答案。 - sashkello
这是实时图像查询。我需要将如此大量的数据存储在内存中,以便对 25GB 的图像数据点进行快速计算。 - Adham Ghazali
2
我认为分配一个大数组并填充它比连接快得多,因为连接每次都会复制整个数组。 - HYRY
4
正如@HYRY建议的那样,首先预分配数组,但是您需要事先知道总大小。问题在于当您执行a = np.concatenate((a, b))时,numpy会创建一个中间数组,其中包含ab的连接,然后将变量a指向它,如果旧的a没有其他引用,则会被垃圾回收。但是,它需要即使只是短暂的一瞬间,您也需要比最终数组多两倍的内存。 - Jaime
显示剩余2条评论
1个回答

4

你的处理过程非常低效。当处理如此大量的数据时,你真的需要了解你的工具。

对于你的问题,禁止使用np.concatenate - 它需要至少两倍于输入的内存。此外,它会复制每一位数据,因此速度也很慢。

  1. 使用numpy.memmap加载数组。这样做只会使用几个字节的内存,同时仍然相当有效。

    使用np.vstack将它们连接在一起。只调用一次(即不要bigArray=vstack(bigArray,newArray)!!!)。将所有数组加载到一个列表allArrays中,然后调用bigArray = vstack(allArrays)

  2. 如果这真的太慢了,你需要预先知道数组的大小,一次性创建一个这样大小的数组,然后将数据加载到现有的数组中(而不是每次都创建一个新的数组)。

    根据磁盘上的文件更改频率,使用操作系统工具将它们连接成一个巨大的文件,然后加载该文件可能更加高效(或者使用numpy.memmap)。


最终我预先分配了 BigArray 的大小并将 newArrays 插入其中。 - Adham Ghazali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接