【问题标题】:Loading numpy files into memory to append arrays causing MemoryError将 numpy 文件加载到内存中以附加数组导致 MemoryError
【发布时间】:2020-08-13 05:41:17
【问题描述】:

尝试运行时:

import numpy as np
import glob

npfiles = glob.glob("*.npy")
npfiles.sort()

for file in npfiles:
    with open(file, 'rb') as f:
        array = np.load(f, allow_pickle=True)
    try:
        test
    except NameError:
        test = array
    else:
        test = np.append(test, array)
array.shape

这是我收到的错误:

MemoryError: Unable to allocate 1.28 GiB for an array with shape (24115,) and data type <U14262

我试图简单地将几个.npy 文件加载到内存中并将它们附加到另一个。它们的总大小只有 1.58GB,而我有 64GB 的物理 RAM。

我发现存在相同问题的 stackoverflow 帖子是由于虚拟内存分配不足,为了克服这个问题,用户通过增加最大页面大小来增加分配的虚拟内存。由于我使用的是 Windows 10,所以我通过 this. 增加了虚拟内存

我已重新启动我的电脑,但仍然遇到此问题。我很困惑。

【问题讨论】:

  • 您能在每次迭代时打印test 大小吗?
  • 您运行的是 32 位还是 64 位版本的 Python?
  • 你还能检查你是否有 64 位 Python 而不是 32 位?另一个小的优化可能是检查数据类型并决定是否可以在不丢失有用信息的情况下向下转换数据 (numpy.org/devdocs/user/basics.types.html)
  • 当您反复使用np.append 时,您需要至少2 个完整副本的空间。 np.concatenate 创建一个新数组,从所有参数中复制值。列表追加最后一个 np.array(...) 效率更高,但在您的情况下可能对整体内存使用没有帮助。
  • @juanpa.arrivillaga 我确信我安装了 64 位版本,但它是 32 位版本。我重新安装了 64 位版本,它运行良好!

标签: python numpy


【解决方案1】:

我重新安装了 64 位版本的 python,因为我有 64 位操作系统和机器。这解决了问题!

【讨论】:

    【解决方案2】:

    当我对我正在使用的数据不屑一顾,读入过多并试图一次存储所有数据时,我一直遇到此错误。我不能 100% 确定您是否能够在加载每个文件时处理每个文件的数据,或者这些文件是否是独立的。

    import numpy as np
    import glob
    
    def process_my_data(data_array):
        . . . 
        # do data processing here
        return processed_data
    
    def do_something_with_all_processed_data(my_processed_data):
        combined_arr = np.array([])
        for k in my_processed_data:
            combined_arr = np.append(processed_data[k], combined_arr)
        print(combined_arr.shape)
        
    def load_and_process_files():
        npfiles = sorted(glob.glob("*.npy"))
        
        my_processed_data = dict()
        for file in npfiles:
            with open(file, 'rb') as f:
                array = np.load(f, allow_pickle=True)
            my_processed_data[file] = process_my_data(array)
        do_something_with_all_processed_data(my_processed_data)
    
    if __name__ == "__main__":
        load_and_process_files()
    

    在大型数据集的情况下,最好将任何进程的输出保存到一个文件中,以便稍后再次读取,这样您就不必总是处理千兆字节的数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-17
      • 2017-04-30
      • 2013-07-08
      • 1970-01-01
      相关资源
      最近更新 更多