如何解决将文件更改为数据框
大家好,我有一个文件,例如;
ORFs.fa
>scaffold_11404_1 [179 - 301]
MLLLKKAQCLTREE
>scaffold_11404_38 [5350 - 3194] (REVERSE SENSE)
MADQKNLQMSRDLALCARHGIPSLFAFLGDIVSTGISQYAISKLMVANLDLSNVDTKLNA
WQTEGGKYYAAEALIRKLDAIDRQMTEPARIACKYGLLVDLRHTLDFATDNMVANARAEV
MLDMRSYHPSNAMLQNNLTRIMVLVKNTPPQSVVSGKQAMRYIPGWQEDLECPMQKYVFF
>scaffold_11404_45 [2557 - 2450] (REVERSE SENSE)
MCKQGICRHTRHLSHIMFKLWNNFKYQNIKETRISD
>scaffold_11404_46 [2311 - 2436]
MIFIELKYSSSLKNYNSSKFNIKNLTKLKHQFYLFFYTFFNT
我需要将其更改为具有 5 列的数据框,例如:
ORF_df
Segments start2 end2 sens sequence
scaffold_11404_1 179 301 normal MLLLKKAQCLTREE
scaffold_11404_38 5350 3194 reverse MADQKNLQMSRDLALCARHGIPSLFAFLGDIVSTGISQYAISKLMVANLDLSNVDTKLNA
WQTEGGKYYAAEALIRKLDAIDRQMTEPARIACKYGLLVDLRHTLDFATDNMVANARAEV
MLDMRSYHPSNAMLQNNLTRIMVLVKNTPPQSVVSGKQAMRYIPGWQEDLECPMQKYVFF
scaffold_11404_45 2557 2450 reverse MCKQGICRHTRHLSHIMFKLWNNFKYQNIKETRISD
scaffold_11404_46 2311 2436 normal MIFIELKYSSSLKNYNSSKFNIKNLTKLKHQFYLFFYTFFNT
有人有想法吗?
到目前为止,我尝试了这段代码,它可以工作,但速度很慢...
ORF_df=pd.DataFrame(columns=("Segments","start2","end2","sens","sequence"))
with open("ORFs.fa") as fasta_file: # Will close handle cleanly
for seq_record in SeqIO.parse(fasta_file,'fasta'): # (generator)
full_name=seq_record.description
sens=re.sub(".*\(","",full_name)
if sens == 'REVERSE SENSE)':
sens="reverse"
else:
sens="normal"
start_end=re.sub(".*\[",full_name)
start_end=re.sub("\].*",start_end)
start_end=start_end.split("-")
start=start_end[0]
end=start_end[1]
sequence=seq_record.seq
Segments=seq_record.id
ORF_df=ORF_df.append({"Segments":re.sub("_[^_]*$",Segments),"sequence":str(sequence),"start2":start,"end2":end,"sens":sens},ignore_index=True)
print(ORF_df)
解决方法
用切片解析文本怎么样。
- 使用正则表达式解析记录;
- 在空白处分割记录;
- 用切片提取相关信息;
- 用信息构建字典;
- 将字典提供给 DataFrame 构造函数。
import pandas as pd
import re
with open("ORFs.fa") as fasta_file:
s = fasta_file.read()
pat = r'^>[^>]+' # pattern to find records
d = {'scaffolding':[],'start':[],'stop':[],'sense':[],'sequence':[]}
for r in re.findall(pat,s,flags=re.M):
scaf,start,_,stop,*rest = r.split()
d['scaffolding'].append(scaf[1:])
d['start'].append(start[1:])
d['stop'].append(stop[:-1])
if rest[0][1:] == 'REVERSE':
sense = 'REVERSE'
i = 2
else:
sense = 'NORMAL'
i = 0
d['sense'].append(sense)
d['sequence'].append(''.join(rest[i:]))
df = pd.DataFrame(d)
print(df)
依赖:
- 文本文件统一
- 没有
>
字符,除了在记录的开头
如果有很多记录,您可能需要使用 re.finditer 而不是 re.findall。
for match in re.finditer(pat,*rest = match.group().split()
...
,
这是一个使用嵌套拆分方法的想法 例如,首先由 '>' 分割,将分隔记录,然后由空格“”分割,将单独的值分开。 您可以一步一步地将所需结果存储在某个变量中 也不要先创建数据帧然后附加到它。像这样创建一个以列名作为键的字典
df = {
"Col1 name": [],"col2 name":[]
}
然后像这样附加到字典中的那个列表
df["Col1 name"].append(value)
最后,您可以从此字典创建数据框
Csv = pd.DataFrame(df)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。