【问题标题】:Splitting up a large file into smaller files at specific points在特定点将大文件拆分为较小的文件
【发布时间】:2020-05-27 05:51:48
【问题描述】:

我知道这个问题已经被问过好几次了。但是这些解决方案在这里真的对我没有帮助。我有一个非常大的文件(大约 5GB)要读取、获取数据并将其提供给我的神经网络。我必须逐行阅读。起初我使用 .readlines() 函数将整个文件加载到内存中,但这显然导致了内存不足的问题。接下来我没有将整个文件加载到内存中,而是逐行读取它,但它仍然没有工作。所以现在我正在考虑将我的文件拆分成更小的文件,然后读取每个文件。对于每个序列,我都有一个以“>”开头的文件格式,后跟一个序列,例如:

>seq1
acgtccgttagggtjhtttttttttt
tttsggggggtattttttttt

>seq2
accggattttttstttttttttaasftttttttt
stttttttttttttttttttttttsttattattat
tttttttttttttttt

>seq3
aa

.
.
.

>seqN
bbbbaatatattatatatatattatatat
tatatattatatatattatatatattatat
tatattatatattatatatattatatatatta
tatatatatattatatatatatatattatatat
tatatatattatatattatattatatatattata
tatatattatatattatatatattatatatatta

所以现在我想将包含 12700000 个序列的文件拆分为更小的文件,这样对于每个带有标题“>”的文件也有正确的对应序列。如何在 python 中实现这一点而不会遇到内存问题。见解将不胜感激。

【问题讨论】:

  • 几个问题:在您的示例中,一些> 后面有一个空格,而另一些则没有。文件也是这样,还是更标准化?在你的标题中,你说“在特定点”——你想如何限制新文件(例如,在某个字符数之后,在这么多序列之后,等等)?我可以看到在 for 循环中使用 while 循环来完成此操作,但可能还有更聪明的方法使用模式和索引。
  • 是的,我在写这个例子时犯了一个错误。所以它没有空间。我也编辑过。所以我在想每个文件有 5000 个序列。我怎样才能做到这一点?
  • 你能解释一下你的逐行方法出了什么问题,也许可以发布代码吗?如果您正确执行此操作,则与读取 n 较小的文件相比应该没有任何区别。

标签: python-3.x


【解决方案1】:

我能够使用 12,700,000 行随机行来做到这一点,每行包含 1-20 个随机字符。虽然我的文件大小远小于 5GB(大约 300MB)——可能是由于格式问题。综上所述,你可以试试这个:

x = 0
y = 1
string = ""
cycle = "Seq1"
with open(f"{FILEPATH}/main.txt", "r") as file:
    for line in file:
        if line[0] == ">":
            if x % 5000 == 0 and x != 0:
                with open(f"{FILEPATH}/Sequence Files/Starting{cycle}.txt", "a") as newfile:
                    newfile.writelines(string)
                cycle = f"Seq{y*5000+1}"
                y += 1
                string = ""
            string += line
            x += 1
        if line[0] != ">":
            string += line
    with open(f"{FILEPATH}/Sequence Files/Starting{cycle}.txt", "a") as newfile:
            newfile.writelines(string)

这将逐行读取文件,将前 5000 个值附加到字符串,将字符串写入新文件,然后对原始文件的其余部分重复。它还将使用文件中的第一个序列命名文件。

读取if x % 5000 == 0: 的行是定义每个文件中序列数的行,cycle = "Seq" + str(y*5000+1) 行创建下一个文件名的格式。如果您改变对每个文件多少个序列的想法(您正在以这种方式创建 2,540 个新文件),您可以调整其中的 5000 个。

【讨论】:

  • 我使用了你的代码。但它最终给我的一堆文件只有一行序列,没有任何标题或任何东西。我似乎不明白为什么会这样。我确实得到了带有相应序列的标题的文件,但大多数文件只有一行序列。
  • 问题出在正在读取的最后一个序列或第 5000 个序列中。它读取标题,然后读取第一行序列,然后将序列的每一行写入不同的文件中,从而创建仅包含一行序列而不是整个序列的文件。
  • 检查缩进。我无法复制这个。它可能与输入文件的格式有关,但如果没有看到它,就很难诊断。
  • 缩进是正确的。我加倍检查。你如何建议我分享我的输入文件。它相当大。格式正是我在示例中给出的。唯一的区别是文件中没有空行。但它不应该根据您编写的代码产生影响,因为您仅在遇到 '>' 时才会递增。
  • 所以我设法部分解决了这个问题。如果我在 if 语句块中添加 x = 1,那么我只需一行序列就可以删除文件。但是每个文件的最后一个序列被拆分的问题仍然存在。所以我在一个文件中有标题和序列的第一行,序列的其余部分是下一个文件的开头。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 2012-06-06
  • 1970-01-01
  • 2012-06-26
  • 1970-01-01
相关资源
最近更新 更多