Python 3.x-如何有效地将对象数组拆分为较小的批处理文件?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Python 3.x-如何有效地将对象数组拆分为较小的批处理文件?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4697字,纯文字阅读大概需要7分钟。
内容图文
![Python 3.x-如何有效地将对象数组拆分为较小的批处理文件?](/upload/InfoBanner/zyjiaocheng/651/12b651889ba44392adc64befe6fa2120.jpg)
我对Python相当陌生,我试图将一个文本文件(其中条目由两行组成)拆分为max. 400个对象.
我正在使用的数据是FASTA格式(带有标头的纯文本,用于生物信息学)的数千个序列,其中的条目如下所示:
>HORVU6Hr1G000325.5
PIPPPASHFHPHHQNPSAATQPLCAAMAPAAKKPPLKSSSSHNSAAGDAA
>HORVU6Hr1G000326.1
MVKFTAEELRGIMDKKNNIRNMSVIAHVD
…
在Biopython中,有一个解析器SeqIO.parse,它允许将它们作为由ID和字符串组成的对象数组进行访问,我需要在代码的后续部分中使用它们,并且由于我需要提高内存效率,因此为了避免不必要的次数读取/解析源文件.
在Biopython手册中,有一种推荐的方式可以通过生成器来实现,我正在使用:https://biopython.org/wiki/Split_large_file
但是,我使用的是Python 3.7,而其中的代码在Python 2.x中,因此肯定需要进行一些更改.我已经改变了
entry = iterator.next()
进入
entry = next(iterator)
但我不确定这是否就是我需要改变的.
这是代码:
def batch_iterator(iterator, batch_size=400):
"""Returns lists of length batch_size."""
entry = True # Make sure we loop once
while entry:
batch = []
while len(batch) < batch_size:
try:
entry = next(iterator)
except StopIteration:
entry = None
if entry is None:
# End of file
break
batch.append(entry)
if batch:
yield batch
while True:
bsequence = input("Please enter the full path to your FASTA file(e.g. c:\\folder1\\folder2\\protein.fasta):\n")
try:
fastafile = open(bsequence)
break
except:
print("File not found!\n")
record_iter = SeqIO.parse(fastafile,"fasta")
num = 0
for line in fastafile:
if line.startswith(">"):
num += 1
print("num=%i" % (num,))
if num > 400:
print("The specified file contains %i sequences. It's recommended to split the FASTA file into batches of max. 400 sequences.\n" % (num,))
while True:
decision = input("Do you wish to create batch files? (Original file will not be overwritten)\n(Y/N):")
if (decision == 'Y' or 'y'):
for i, batch in enumerate(batch_iterator(record_iter, 400), 1):
filename = "group_%i.fasta" % (i + 1)
with open(filename, "w") as handle:
count = SeqIO.write(batch, handle, "fasta")
print("Wrote %i records to %s" % (count, filename))
break
elif (decision == 'N' or 'n'):
break
else:
print('Invalid input\n')
...next part of the code
当我运行此命令时,在Y / N提示符后,即使我键入Y,该程序也将跳过代码的下一部分而不创建任何新文件.调试器显示以下内容:
Do you wish to create batch files? (Original file will not be overwritten)
(Y/N):Y
Traceback (most recent call last):
File "\Biopython\mainscript.py", line 32, in batch_iterator
entry = next(iterator)
StopIteration
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Program Files (x86)\Thonny\lib\site-packages\thonny\backend.py", line 1569, in _trace
return self._trace_and_catch(frame, event, arg)
File "C:\Program Files (x86)\Thonny\lib\site-packages\thonny\backend.py", line 1611, in _trace_and_catch
frame.f_back, event, marker_function_args, node
File "C:\Program Files (x86)\Thonny\lib\site-packages\thonny\backend.py", line 1656, in _handle_progress_event
self._save_current_state(frame, event, args, node)
File "C:\Program Files (x86)\Thonny\lib\site-packages\thonny\backend.py", line 1738, in _save_current_state
exception_info = self._export_exception_info()
File "C:\Program Files (x86)\Thonny\lib\site-packages\thonny\backend.py", line 1371, in _export_exception_info
"affected_frame_ids": exc[1]._affected_frame_ids_,
AttributeError: 'StopIteration' object has no attribute '_affected_frame_ids_'
我忽略的Python 2.x和3.x之间有什么区别吗?问题在其他地方吗?这种方法完全错误吗?提前致谢!
解决方法:
由于您省略了一部分代码,因此我无法检查整个代码,但在这里我会看到两处错误的内容:
num = 0
for line in fastafile:
if line.startswith(">"):
num += 1
这些行耗尽了您的文件对象fastafile.完全删除这些行(并记住要修复下面的缩进,如果num> 400:请取消,等等).
if (decision == 'Y' or 'y'):
这并没有按照您的想法做.将其更改为if决策(‘Y’,’y’):或if Decision.lower()==’y’:.您在下面的if(decision ==’N’或’n’):行中重复此模式,因此也进行更改.
进行更改,然后尝试再次运行代码.
说明
第一个问题:在Python中,文件对象(即open(‘filename.txt’,’r’)返回的内容)是一个生成器,这意味着它只能被迭代一次.乍一看这似乎有些怪异,但这就是使用生成器的全部意义所在.生成器作为文件对象允许文件逐行循环,而不必一次加载整个文件内容-生成器仅跟踪下一行.
缺点是它们不能向后移动,因此当您在fastafile块中编写for行时,将耗尽生成器.当您稍后尝试调用batch_iterator(record_iter,400)时,record_iter中的生成器已经用尽,这就是为什么您以后会遇到错误的原因-如果没有任何要解析的内容,batch_iterator无法解析fasta序列.
第二个问题:对于带有布尔运算符的条件,例如if(decision ==’Y’或’y’):, Python将始终分别评估双方.因此,Python实际上会查看(bool(decision ==’Y’)还是bool(‘y’)):.
由于bool(‘y’)的计算结果为True(就像任何非空字符串一样),因此您的表达式变为if(bool(decision ==’Y’)或True):,这显然总是对的.
使用我建议的一种方法,以便将变量与条件中的多个值进行比较.
内容总结
以上是互联网集市为您收集整理的Python 3.x-如何有效地将对象数组拆分为较小的批处理文件?全部内容,希望文章能够帮你解决Python 3.x-如何有效地将对象数组拆分为较小的批处理文件?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。