gpt4 book ai didi

python - 如何将文件中具有相同值的所有行保存到文件中

转载 作者:太空宇宙 更新时间:2023-11-03 17:55:16 26 4
gpt4 key购买 nike

我编写了一个Python脚本,该脚本从CIF文件生成字典。我用这样的文件[1qpe,使用4105行->时间:383ms(毫秒)]或使用了这个文件(1d66,使用3274行->时间:225ms)进行了测试,但是当我尝试使用该文件时(4tvx,具有170925行),花费很长时间,以至于我决心阻止该过程。我当时想拆分CIF文件,从中推断出以ATOM和HETATM开头的行:

实际上,从每个原始CIF文件开始,目的是首先获取4个文件:


包含我称为header的文件=以ATOM和HETATM开头的行循环上方的所有行
一个仅包含循环的26行的文件
包含以ATOM和HETATM开头的所有行的文件
包含所有其余行的文件,我称之为页脚


到这里我解决了,对于1d66用34毫秒,对于1qpe用43毫秒,对于4tvx用1.923s。
现在,获得了第三个文件(所有过程的目标,因为是字典的输入),我想从中推断出具有相同第七列的所有行,并将它们写到一个专用文件中,并用将第7列作为文件名,对第7列的所有值重复此操作。

这是我的代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys, os
import os.path
scriptdir = os.path.dirname(os.path.abspath(__file__))
cif_dir = os.path.join(scriptdir, 'cif/')

def get_line_number(phrase, file_name):
with open(file_name) as f:
for i, line in enumerate(f, 1):
if phrase in line:
return i

def my_header_splitfile(infilepath, chunksize):
fname, ext = infilepath.rsplit('.',1)
with open(infilepath) as infile:
outfilepath = "{}_header.{}".format(fname, ext)
with open(outfilepath, 'w') as outfile:
for line in (infile.readline() for _ in range(0,(chunksize-2))):
outfile.write(line) # END
temp_lines = open(infilepath).readlines()
temp_outfilepath = "{}_temp.{}".format(fname, ext)
atom_hetatm_header_outfilepath = "{}_atom_hetatm_header.{}".format(fname, ext)
with open(atom_hetatm_header_outfilepath, 'w') as outfile:
outfile.writelines(temp_lines[(chunksize-2):(chunksize+25)])
with open(temp_outfilepath, 'w') as outfile:
outfile.writelines(temp_lines[(chunksize+25):-1]) # END
footer_lines = open(temp_outfilepath).readlines()
footer_outfilepath = "{}_footer.{}".format(fname, ext)
with open(footer_outfilepath, 'w') as outfile:
for line in footer_lines:
if not (line.startswith('ATOM') or line.startswith('HETATM')):
outfile.writelines(line) # END
temp_atom_hetatm_lines = open(temp_outfilepath).readlines()
temp_atom_hetatm_outfilepath = "{}_atom_hetatm.{}".format(fname, ext)
with open(temp_atom_hetatm_outfilepath, 'w') as outfile:
for line in temp_atom_hetatm_lines:
if (line.startswith('ATOM') or line.startswith('HETATM')):
outfile.writelines(line) # END
os.remove(temp_outfilepath) # FINISH
"""BEGIN TO SPLIT THE 'ATOM'"""
"""
with open(temp_atom_hetatm_outfilepath,'r') as infile:
lines = infile.readlines()

rows_list = list()
chains_list = list()
for line in lines:
col = line.split(None)
rows_list.append(col)
#print line
#if col[0] == "HETATM":
# print "HETATM record"
if col[0] == "ATOM":
#print col[0]
# FILTER FOR ONLY PROTEINS AND NUCLEIC ACIDS
if (col[3] == "N" or col[3] == "N1"):
chains_list.append(col[6])
chains_list_cleaned = list(set(chains_list))
for chain in chains_list_cleaned:
if col[6] == chain:
atom_chain_outfilepath = "{}_atom_chain_{}.{}".format(fname, chain, ext)
with open(atom_chain_outfilepath, 'w') as outfile:
#outfile.writelines("Hello")
outfile.writelines(line) # END
"""

cif_code = '1d66'.upper() # CHANGE HERE THE PID CODE. i.e. 1D66, 1QPE, 4TVX

filename = '%s%s.cif' % (cif_dir,cif_code.upper())

begin_atom = get_line_number("_atom_site.group_PDB", filename)
#print begin_atom
my_header_splitfile(filename, begin_atom)


如果取消注释最后几行:

""" with open(temp_atom_hetatm_outfilepath,'r') as infile:
lines = infile.readlines()

rows_list = list()
chains_list = list()
for line in lines:
col = line.split(None)
rows_list.append(col)
#print line
#if col[0] == "HETATM":
# print "HETATM record"
if col[0] == "ATOM":
#print col[0]
# LIMITO ALLE SOLE PROTEINE E ACIDI NUCLEICI
if (col[3] == "N" or col[3] == "N1"):
chains_list.append(col[6])
chains_list_cleaned = list(set(chains_list))
for chain in chains_list_cleaned:
if col[6] == chain:
atom_chain_outfilepath = "{}_atom_chain_{}.{}".format(fname, chain, ext)
with open(atom_chain_outfilepath, 'w') as outfile:
#outfile.writelines("Hello")
outfile.writelines(line) # END
"""


您会看到我可以为每个链保存一个文件(例如,在生成的“ 1d66_atom_hetatm.cif”文件中的第七列),但是在每个文件中只写入一行,而不是该链的所有行(第七列) )。如何实现呢?

谢谢,

里卡多

编辑1:
您只需更改带有下载的cif文件的第72行就可以对其进行测试!

================================================== ====================
================================================== ====================

编辑2:
这是生成的“ 1D66_atom_hetatm.cif”中内容的示例:

ATOM   378  C  C8    . DG  A 1 19 ? 34.329 11.346 27.800 1.00 29.46 ? ? ? ? ? ? 19  DG  D C8    1 
ATOM 379 N N7 . DG A 1 19 ? 34.046 11.420 26.537 1.00 31.63 ? ? ? ? ? ? 19 DG D N7 1
ATOM 380 C C5 . DG A 1 19 ? 32.698 11.672 26.542 1.00 26.85 ? ? ? ? ? ? 19 DG D C5 1
ATOM 381 C C6 . DG A 1 19 ? 31.860 11.863 25.447 1.00 26.53 ? ? ? ? ? ? 19 DG D C6 1
ATOM 382 O O6 . DG A 1 19 ? 32.175 11.864 24.251 1.00 32.03 ? ? ? ? ? ? 19 DG D O6 1
ATOM 383 N N1 . DG A 1 19 ? 30.569 12.079 25.868 1.00 23.18 ? ? ? ? ? ? 19 DG D N1 1
ATOM 384 C C2 . DG A 1 19 ? 30.136 12.115 27.159 1.00 23.53 ? ? ? ? ? ? 19 DG D C2 1
ATOM 385 N N2 . DG A 1 19 ? 28.819 12.261 27.325 1.00 19.29 ? ? ? ? ? ? 19 DG D N2 1
ATOM 386 N N3 . DG A 1 19 ? 30.949 11.949 28.200 1.00 26.27 ? ? ? ? ? ? 19 DG D N3 1
ATOM 387 C C4 . DG A 1 19 ? 32.213 11.729 27.819 1.00 25.75 ? ? ? ? ? ? 19 DG D C4 1
ATOM 388 O "O5'" . DC B 2 1 ? 20.466 11.694 21.639 1.00 40.14 ? ? ? ? ? ? 20 DC E "O5'" 1
ATOM 389 C "C5'" . DC B 2 1 ? 21.891 11.609 21.791 1.00 29.52 ? ? ? ? ? ? 20 DC E "C5'" 1
ATOM 390 C "C4'" . DC B 2 1 ? 22.246 11.659 23.274 1.00 28.85 ? ? ? ? ? ? 20 DC E "C4'" 1
ATOM 391 O "O4'" . DC B 2 1 ? 23.643 11.328 23.562 1.00 27.78 ? ? ? ? ? ? 20 DC E "O4'" 1
ATOM 392 C "C3'" . DC B 2 1 ? 22.093 13.078 23.713 1.00 26.83 ? ? ? ? ? ? 20 DC E "C3'" 1
ATOM 393 O "O3'" . DC B 2 1 ? 21.761 13.021 25.064 1.00 26.10 ? ? ? ? ? ? 20 DC E "O3'" 1
ATOM 394 C "C2'" . DC B 2 1 ? 23.541 13.575 23.586 1.00 27.66 ? ? ? ? ? ? 20 DC E "C2'" 1
ATOM 395 C "C1'" . DC B 2 1 ? 24.295 12.435 24.176 1.00 21.82 ? ? ? ? ? ? 20 DC E "C1'" 1


我想将所有在第七列(从0开始)中带有A的行保存在1d66_A.txt文件中,并将所有在第七列中带有B的行保存在1d66_B.txt文件中,以此类推。从脚本生成的文件的第七列。

最终输出应为:

文件1D66_A.txt:

ATOM   378  C  C8    . DG  A 1 19 ? 34.329 11.346 27.800 1.00 29.46 ? ? ? ? ? ? 19  DG  D C8    1 
ATOM 379 N N7 . DG A 1 19 ? 34.046 11.420 26.537 1.00 31.63 ? ? ? ? ? ? 19 DG D N7 1
ATOM 380 C C5 . DG A 1 19 ? 32.698 11.672 26.542 1.00 26.85 ? ? ? ? ? ? 19 DG D C5 1
ATOM 381 C C6 . DG A 1 19 ? 31.860 11.863 25.447 1.00 26.53 ? ? ? ? ? ? 19 DG D C6 1
ATOM 382 O O6 . DG A 1 19 ? 32.175 11.864 24.251 1.00 32.03 ? ? ? ? ? ? 19 DG D O6 1
ATOM 383 N N1 . DG A 1 19 ? 30.569 12.079 25.868 1.00 23.18 ? ? ? ? ? ? 19 DG D N1 1
ATOM 384 C C2 . DG A 1 19 ? 30.136 12.115 27.159 1.00 23.53 ? ? ? ? ? ? 19 DG D C2 1
ATOM 385 N N2 . DG A 1 19 ? 28.819 12.261 27.325 1.00 19.29 ? ? ? ? ? ? 19 DG D N2 1
ATOM 386 N N3 . DG A 1 19 ? 30.949 11.949 28.200 1.00 26.27 ? ? ? ? ? ? 19 DG D N3 1
ATOM 387 C C4 . DG A 1 19 ? 32.213 11.729 27.819 1.00 25.75 ? ? ? ? ? ? 19 DG D C4 1


文件1D66_B.txt:

ATOM   388  O  "O5'" . DC  B 2 1  ? 20.466 11.694 21.639 1.00 40.14 ? ? ? ? ? ? 20  DC  E "O5'" 1 
ATOM 389 C "C5'" . DC B 2 1 ? 21.891 11.609 21.791 1.00 29.52 ? ? ? ? ? ? 20 DC E "C5'" 1
ATOM 390 C "C4'" . DC B 2 1 ? 22.246 11.659 23.274 1.00 28.85 ? ? ? ? ? ? 20 DC E "C4'" 1
ATOM 391 O "O4'" . DC B 2 1 ? 23.643 11.328 23.562 1.00 27.78 ? ? ? ? ? ? 20 DC E "O4'" 1
ATOM 392 C "C3'" . DC B 2 1 ? 22.093 13.078 23.713 1.00 26.83 ? ? ? ? ? ? 20 DC E "C3'" 1
ATOM 393 O "O3'" . DC B 2 1 ? 21.761 13.021 25.064 1.00 26.10 ? ? ? ? ? ? 20 DC E "O3'" 1
ATOM 394 C "C2'" . DC B 2 1 ? 23.541 13.575 23.586 1.00 27.66 ? ? ? ? ? ? 20 DC E "C2'" 1
ATOM 395 C "C1'" . DC B 2 1 ? 24.295 12.435 24.176 1.00 21.82 ? ? ? ? ? ? 20 DC E "C1'" 1


很抱歉,我正在尽力向自己解释自己,谢谢您的帮助。

步骤是串联的,所以我不能拆分脚本:可以尝试...问题很简单,我只是想获取Edit 2中所说的内容,即读取第6列(从0开始,其中您在该示例中阅读了AAAAAAABBBBBBBB),将其中包含A的所有行复制到一个名为“ 1d66_A.txt”的文件中,并将所有包含B的行复制到另一个文本文件“ 1d66_B.txt”中,就像在Edit 2中一样。要测试我所做的事情,只需将该脚本复制并粘贴到扩展名为.py的文本文件中(例如my_script.py);在该脚本的同一文件夹中,创建一个文件夹“ cif”,并将从这些链接下载的cif文件(例如1d66,如果您不想编辑脚本的第72行)放入其中;最后使用命令“ python my_script.py”在外壳程序中运行脚本(我正在使用Linux):脚本生成四个文件。在本主题中,我将自己参考生成的“ 1d66_atom_hetatm.cif”文件,如我所说,我希望将其拆分为“ 1d66_A.txt”,“ 1d66_B.txt”,“ 1d66_C.txt”,“ 1d66_D.txt”( 4个文件,因为在1d66中,以ATOM开头的所有行的第6列(从0开始)有4个不同的字母),例如EDIT 2。

================================================== ====================
================================================== ====================

编辑3-@qwwqwwq

我将尝试用文字解释剧本;假设此顺序:


  HHHHHLLLLLAAAAABBBBBFFFFF


这是我对CIF文件的起点和终点的一种方案,在使用python对其进行详细说明之前先对其进行合理化,其中:

H = header
L = loop for ATOM and HETATM rows
A = chain A (= column 7) in ATOM
B = chain B (= column 7) in ATOM
F = footer


现在,我需要拆分通用cif文件的所有这些部分。为此,我正在编写此脚本,该脚本现在可以生成:

H
L
A+B
F


所以我需要将A与B分开!
为什么使用临时文件?让我解释;这些步骤:


检查ATOM和HETATM行的LOOP在哪里。为此,我搜索字符串“ _atom_site.group_PDB”(脚本的最后三行),然后使用函数“ get_line_number”获得相对行号。我知道循环的长度为26行,所以现在我知道循环的开始和结束位置(开始= begin_atom =“ get_line_number”函数的输出;结束= begin_atom之后的26行,即25行,因为“范围”从0开始,而get_line_number函数从1开始)。因此,现在我可以将循环保存在单独的文件中。
我也可以保存标题(H),因为它从行0开始到行“ begin_atom”(“ get_line_number”函数的输出)
现在,对于A,B和F,我使用了该临时文件(临时文件,因为我最后将其删除了)。我从循环末尾生成临时文件[=(“ begin_atom” +26),即25,因为范围从0开始到文件末尾(“ -1”行),然后将其保存为临时文件,用作写页脚(F)的输入;怎么做?使用构造:

if not (line.startswith('ATOM') or line.startswith('HETATM'))

这样我现在也可以保存页脚!
现在剩下的工作就是拆分以ATOM和HETATM开头的记录中的所有链条(第7列),为此我打开了这个主题。我以为我在编辑2中写了什么。实际上,链(第7列)可以是一个(如文件1QPE中的)或许多(如4TVX文件中的,其中有22个链,即22个不同的字母)在以ATOM或HETATM开头的每一行的第7列中)。


我在脚本中以注释的方式尝试过(请参见EDIT 1之前的内容),该脚本为每个链保存了一个文件(第7列中的不同字母),但是在每个文件中仅写入了ATOM行。清楚,正确地表达了自己

================================================== ====================
================================================== ====================

解决-感谢@qwwqwwq

@qwwqwwq :-)谢谢。我一直在寻找“ cif”文件夹中的输出,却没有意识到,对代码进行少量编辑(请参阅我的编辑)之后,脚本会将文件保存在同一文件夹中:-D。完善!

最终版本在:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys, os
import os.path
scriptdir = os.path.dirname(os.path.abspath(__file__))
cif_dir = os.path.join(scriptdir, 'cif/')

def get_line_number(phrase, file_name):
with open(file_name) as f:
for i, line in enumerate(f, 1):
if phrase in line:
return i

def my_header_splitfile(infilepath, chunksize):
fname, ext = infilepath.rsplit('.',1)
with open(infilepath) as infile:
outfilepath = "{}_header.{}".format(fname, ext)
with open(outfilepath, 'w') as outfile:
for line in (infile.readline() for _ in range(0,(chunksize-2))):
outfile.write(line) # END
temp_lines = open(infilepath).readlines()
temp_outfilepath = "{}_temp.{}".format(fname, ext)
atom_hetatm_header_outfilepath = "{}_atom_hetatm_header.{}".format(fname, ext)
with open(temp_outfilepath, 'w') as outfile:
outfile.writelines(temp_lines[(chunksize+25):-1]) # END
with open(atom_hetatm_header_outfilepath, 'w') as outfile:
outfile.writelines(temp_lines[(chunksize-2):(chunksize+25)])
footer_lines = open(temp_outfilepath).readlines()
footer_outfilepath = "{}_footer.{}".format(fname, ext)
with open(footer_outfilepath, 'w') as outfile:
for line in footer_lines:
if not (line.startswith('ATOM') or line.startswith('HETATM')):
outfile.writelines(line) # END
temp_atom_hetatm_lines = open(temp_outfilepath).readlines()
temp_atom_hetatm_outfilepath = "{}_atom_hetatm.{}".format(fname, ext)
with open(temp_atom_hetatm_outfilepath, 'w') as outfile:
for line in temp_atom_hetatm_lines:
if (line.startswith('ATOM') or line.startswith('HETATM')):
outfile.writelines(line) # END
"""NEW ENTRY"""
with open(temp_atom_hetatm_outfilepath) as infile:
for line in infile:
if line.startswith("ATOM"):
atom_chain_outfilepath = "{}_atom_chain_{}.{}".format(fname, line.split()[6], ext)
with open(atom_chain_outfilepath, "a") as outfile:
outfile.write(line)
elif line.startswith("HETATM"):
atom_chain_outfilepath = "{}_hetatm_chain_{}.{}".format(fname, line.split()[6], ext)
with open(atom_chain_outfilepath, "a") as outfile:
outfile.write(line)
os.remove(temp_outfilepath) # REMOVE "temp_outfilepath"
os.remove(temp_atom_hetatm_outfilepath) # REMOVE "temp_atom_hetatm_outfilepath" - FINISH

cif_code = '1d66'.upper() # CHANGE HERE THE PID CODE. i.e. 1D66, 1QPE, 4TVX

filename = '%s%s.cif' % (cif_dir,cif_code.upper())

begin_atom = get_line_number("_atom_site.group_PDB", filename)
#print begin_atom
my_header_splitfile(filename, begin_atom)


现在,您需要编辑PID条目的第55行(即1d66、1qpe,4tvx,...,从Protein Data Bank下载)。

最佳答案

很难在这里说出您的要求,对此感到抱歉。提供适合您的问题主体的样本输入和输出将大有帮助。

听起来您想根据文件第六列中的值拆分文件。

我会做类似的事情:

def meets_criteria(line):
return line.startswith("ATOM") or line.startswith("HETATM")

with open(large_file) as f:
for line in f:
if meets_criteria(line):
with open(line.split()[6], "a") as of:
of.write(line)


因此,您将拥有以第六列中的值命名的文件(索引为0)。

您似乎经常使用 .readlines方法,请注意,这会将所有数据读取到内存中,没有理由这样做,这可能是脚本挂在大输入上的原因。

关于python - 如何将文件中具有相同值的所有行保存到文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28552413/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com