如何随机化文本文件中的所有行而不必将它们保存到变量中?

How can I randomize all lines in a textfile without having to save them to a variable?

在我创建一个训练国际象棋位置的神经网络的项目中,我从 database.lichess.org 下载了 7000 万场比赛,并从每场比赛中提取每一步的位置,并保存输赢和平局位置到不同的文件。

我现在几乎可以开始训练我的神经网络了,但如果我现在开始训练,这些位置将按游戏聚集在一起 - 例如前 90 个位置(每半步后 45 步游戏的前 90 个位置)将来自同一个游戏。这意味着几乎整个训练迭代都会严重偏向某个游戏的结果。

显而易见的解决方案是随机化文本文件中的每一行,但我知道如何做到这一点的唯一方法是这样的:

import random as rand


def shuffle_lines(textfile_location):
    textfile_lines_list = []

    with open(textfile_location, "r") as textfile:

        for line in textfile.readlines():
            textfile_lines_list.append(line)

    rand.shuffle(textfile_lines_list)
    
    with open(textfile_location, "w") as textfile:
        textfile.truncate()
        
        for line in textfile_lines_list:
            textfile.write(line)

考虑到我正在洗牌的数据量(~70'000'000 场比赛 * 70 个半步 = ~4'900'000'000 个位置),我担心这会花费大量时间,因为我首先必须将文本文件中的每个项目复制到列表中,然后打乱列表,然后将列表复制回文本文件。

有没有更有效的方法来做到这一点,例如洗牌文本文件而不先复制到列表?

(编辑:更新我的回答以反映@Maxijazz 的评论)

这里有一个更简单的方法来代替洗牌(这里n是当前文件中的行数):

使用numpy.random.permutation(n-1)。这将 return 一个包含整数 [0,1...,n-1] 随机排列的数组。您可以简单地按顺序使用这些元素来创建“洗牌”效果。

我想建议一个不同的方法:

在神经网络上,如果你在训练开始时有偏见,通常有两件事要做:

  • 增加批次大小(减少批次中每个游戏的偏差)

  • 降低或改变学习率(刚开始会出现较小的权重变化)