【问题标题】:Prevent python3 process being 'Killed' by not having enough memory通过没有足够的内存来防止 python3 进程被“杀死”
【发布时间】:2020-08-11 01:32:26
【问题描述】:

我正在尝试连接两个大型数字矩阵,第一个:features 是一个np.array 形状的1238,72,另一个是从.json 文件加载的,如第二个所示下面的线,它的形状是1238, 768。我需要加载、连接、重新索引、拆分为折叠并将每个折叠保存在自己的文件夹中。问题是我在第一步得到Killed(将.json 内容读入bert

with open(bert_dir+"/output4layers.json", "r+") as f:
    bert = [json.loads(l)['features'][0]['layers'][0]['values'] for l in f.readlines()]

    bert_post_data = np.concatenate((features,bert), axis=1)
    del bert

    bert_post_data = [bert_post_data[i] for i in index_shuf]
    bert_folds = np.array_split(bert_post_data, num_folds)
    for i in range(num_folds):
        print("saving bert fold ",str(i), bert_folds[i].shape)
        fold_dir = data_dir+"/folds/"+str(i)
        save_p(fold_dir+"/bert", bert_folds[i])

有没有办法可以有效地提高内存?我的意思是,一定有更好的方法...... pandas,json lib?

感谢您的时间和关注

【问题讨论】:

    标签: python json pandas optimization memory


    【解决方案1】:

    试试:

    bert = [json.loads(line)['features'][0]['layers'][0]['values'] for line in f]
    

    这样你至少不会一次读取内存中的整个文件——也就是说,如果文件很大,你必须进一步处理你存储在bert中的内容

    【讨论】:

    • 是的,我正在阅读其他类似的问题,似乎readlines() 是一个大错误。显然我应该每行做处理线。问题是我需要应用重新索引...我怎么可能做到这一点?
    • 应用重新索引@LucasAzevedo 是什么意思?
    • 在上面显示的代码截断之前,我已经“洗牌”了分配给该数据的标签。 index_shuf 变量保留了该改组中使用的顺序,因此我可以对bertfeatures 串联产生的矩阵应用相同的改组。有没有一种方法可以执行此操作而无需将整个内容加载到内存中?
    • 你可以做bert_post_data[index_shuf]
    【解决方案2】:

    我在搜索类似问题时发现了这个solution。它不是在特定问题中投票最多的,但在我看来它比任何东西都好。

    这个想法很简单:不是保存一个字符串列表(文档中的每一行一个),而是保存一个引用每一行的文件索引位置列表,然后当你想访问它的内容时,你只需要seek 到这个内存位置。为此,LineSeekableFile 类就派上用场了。

    唯一的问题是您需要在整个过程中保持文件对象(而不是整个文件!)打开。

    class LineSeekableFile:
        def __init__(self, seekable):
            self.fin = seekable
            self.line_map = list() # Map from line index -> file position.
            self.line_map.append(0)
            while seekable.readline():
                self.line_map.append(seekable.tell())
    
        def __getitem__(self, index):
            # NOTE: This assumes that you're not reading the file sequentially.
            # For that, just use 'for line in file'.
            self.fin.seek(self.line_map[index])
            return self.fin.readline()
    

    然后访问它:

    b_file = bert_dir+"/output4layers.json"
    
    fin = open(b_file, "rt")
    BertSeekFile = LineSeekableFile(fin)
    
    b_line = BertSeekFile[idx] #uses the __getitem__ method
    
    fin.close()
    

    【讨论】:

      猜你喜欢
      • 2022-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多