python - 优化大型级联文件/循环的脚本以从文件列表中丢弃有缺陷的项目
问题描述
编辑:用真实示例替换示例文件;nbratoms
将变量替换为nbrbonds
.
初学者问题。
我想针对大文件(100G+)优化以下脚本。我昨天发现了 itertools 的存在,但没有任何线索。
f = open(sys.argv[1], "r")
out = open(sys.argv[2], 'w')
lines = f.read().split('\n@<TRIPOS>MOLECULE')
for i in lines:
ii=i.split('\n@<TRIPOS>',4)
header=ii[0]
infos=header.split('\n')[2]
nbrbonds=infos.split(' ')[2]
if str(nbrbonds) in ii[2]:
out.write('\n@<TRIPOS>MOLECULE'+str(i))
out.close()
f.close()
处理后的文件由串联的 200,000+ 个 MOL2 文件组成(下面的最后一个示例)。该脚本的想法是首先将输入文件拆分为由两个分隔的项目@<TRIPOS>MOLECULE
(=新 MOL2 文件的第一行);然后根据以开头的行将这些项目拆分为 4个@<TRIPOS>
部分(即@<TRIPOS>MOLECULE
、@<TRIPOS>ATOM
和)。对于每个单个 MOL2 文件,我想检查标题中(第二个)位置的值是否(在每个单个 MOL2 文件中不同) @<TRIPOS>BOND
@<TRIPOS>ALT_TYPE
14
@<TRIPOS>MOLECULE
Z1198223644
14 14 0 0 0
USER_CHARGES
出现在单个文件的第三部分(下):
@<TRIPOS>BOND
1 1 2 1
2 2 3 1
3 2 4 1
4 2 5 1
5 5 6 ar
6 5 11 ar
...
如果确实如此-> 将其\n@<TRIPOS>MOLECULE
作为第一行打印到输出文件(基本上只是单个 MOL2 文件的外观)。它似乎按原样工作,但我担心它太业余了。此外,我不知道如何实现一个步骤,以避免输出文件以这样的双标头标记开头
@<TRIPOS>MOLECULE@<TRIPOS>MOLECULE
Z1198223644
...
欢迎任何帮助!我加入了一个包含 6 个串联 MOL2 文件的文件;奇数文件是正确的;甚至文件- 错误。
@<TRIPOS>MOLECULE
Z1198223644
14 14 0 0 0
USER_CHARGES
@<TRIPOS>ATOM
1 F1 23.5932 2.0831 -52.2012 F 1 LIG -0.15900
2 C2 22.4195 1.3866 -52.4217 C.3 1 LIG 0.88300
3 F3 22.5324 0.1265 -51.8643 F 1 LIG -0.15900
4 F4 21.3805 2.0570 -51.7993 F 1 LIG -0.15900
5 C5 22.1912 1.2555 -53.9016 C.ar 1 LIG 0.04500
6 C6 21.0466 1.7681 -54.5284 C.ar 1 LIG -0.13400
7 C7 20.8964 1.6126 -55.9046 C.ar 1 LIG -0.19400
8 C8 21.8881 0.9505 -56.6271 C.ar 1 LIG 0.20700
9 O9 21.7710 0.7997 -57.8724 O.2 1 LIG -0.49500
10 N10 22.9825 0.4691 -55.9778 N.ar 1 LIG 0.11300
11 N11 23.1254 0.6186 -54.6592 N.ar 1 LIG -0.68800
12 H12 20.2773 2.2819 -53.9665 H 1 LIG 0.21400
13 H13 20.0176 2.0033 -56.4027 H 1 LIG 0.20000
14 H14 23.7285 -0.0277 -56.5143 H 1 LIG 0.32600
@<TRIPOS>BOND
1 1 2 1
2 2 3 1
3 2 4 1
4 2 5 1
5 5 6 ar
6 5 11 ar
7 6 7 ar
8 7 8 ar
9 8 9 2
10 8 10 ar
11 10 11 ar
12 6 12 1
13 7 13 1
14 10 14 1
@<TRIPOS>ALT_TYPE
CGenFF_4.0_ALT_TYPE_SET
CGenFF_4.0 1 FGA3 2 CG302 3 FGA3 4 FGA3 5 CG2R62 6 CG2R62 7 CG2R62 8 CG2R63 9 OG2D4 10 NG2R61 11 NG2R62 12 HGR62 13 HGR62 14 HGP1
解决方案
对于文件行的内存有效读取(即拆分\n
或特定于操作系统的行结尾),您可以使用:
with open(sys.argv[1], "r") as f, open(sys.argv[2], 'w') as out:
for i in f:
...
但你需要拆分'\n@<TRIPOS>MOLECULE'
,所以我建议创建你自己的生成器(一个函数yield
)来生成 MOLECULE 块,只将 1 个块加载到内存中(懒惰读取大文件,而不是使用贪婪read()
):
def mol_reader(file_stream):
chunk = []
for line in file_stream:
line = line.strip()
if line == "@<TRIPOS>MOLECULE":
if chunk:
yield chunk
chunk = []
else:
chunk.append(line)
yield chunk
with open(sys.argv[1], "r") as f, open(sys.argv[2], 'w') as out:
for mol_file in mol_reader(f):
...
推荐阅读
- javascript - 将坐标数组转换为 google.maps.LatLng 数组
- python - 从列表中成对嵌套列表
- java - spring maven安装或清理错误,为什么?
- c++ - 带有acos的两个向量之间的C ++角度
- r - 累积分组
- .htaccess - 如何将 Magento 2 与 openlitespeed(免费)网络服务器一起使用?
- docker - Docker Nginx 反向代理,用于保护 Docker 容器
- html - 通过nodeJS从HTML页面解析formdata时获取“SyntaxError:Unexpected token if”
- php - 使用 PHP 在服务器上解压缩文件时的目录结构
- python - 为 Python 和 Python 3 安装 OpenCV