EDIT:用真实示例替换示例文件;将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文件的第一行)分隔的项目;然后根据以@<TRIPOS>
开头的行将这些项目分成4部分(即@<TRIPOS>MOLECULE
,@<TRIPOS>ATOM
,@<TRIPOS>BOND
和@<TRIPOS>ALT_TYPE
)。对于每个单个MOL2文件,我想检查标头中(第二个)14
(每个单个MOL2文件中的不同)的位置处的值
@<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
作为第一行将其打印到outputfile(本质上就是单个MOL2文件的外观)。
它似乎可以正常工作,但是我担心它太业余了。另外,我不知道如何执行避免输出文件以这样的双头标记开头的步骤
@<TRIPOS>MOLECULE@<TRIPOS>MOLECULE
Z1198223644
...
欢迎任何帮助!我加入了一个file,其中包含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
答案 0 :(得分:0)
要获得内存有效的文件行读取效果(例如,用\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):
...