优化大型合并文件的脚本/循环以排除文件列表中的缺陷项目

2024-05-23 15:08:46 发布

您现在位置:Python中文网/ 问答频道 /正文

EDIT:用一个真实的示例替换示例文件;用nbrbonds替换nbratoms变量。你知道吗

初学者问题。你知道吗

我想优化巨大的文件(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()

处理后的文件由串联的200000+个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
 ...

如果是->;将其打印到outputfile,第一行是\n@<TRIPOS>MOLECULE(基本上就是单个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

Tags: 文件示例typeoutaltiisplitar
1条回答
网友
1楼 · 发布于 2024-05-23 15:08:46

对于文件行的内存高效读取(即按\n或操作系统特定的行结尾拆分),您可以使用:

with open(sys.argv[1], "r") as f, open(sys.argv[2], 'w') as out:
    for i in f:
        ...

但是您需要按'\n@<TRIPOS>MOLECULE'拆分,因此我建议您创建自己的生成器(一个带有yield的函数)来生成分子块,只将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):
        ...

例如https://repl.it/@PeterAprillion/chunk-iterator

相关问题 更多 >