将文件更改为数据框
Change a file into a dataframe
大家好,我有一个文件,例如 ;
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)
这是一个使用嵌套拆分方法的想法
例如,首先用 '>' 分割,这将分隔记录,然后用 space " " 分割,这将分隔各个值。
您可以一次进行一个步骤,将所需结果存储在某个变量中
也不要先创建数据框然后附加到它。像这样创建一个以列名作为键的字典
df = {
"Col1 name": [],
"col2 name":[]
}
然后像这样追加到字典中的那个列表
df["Col1 name"].append(value)
你终于可以从这个字典创建数据框了
Csv = pd.DataFrame(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,s,flags=re.M):
scaf,start,_,stop,*rest = match.group().split()
...
大家好,我有一个文件,例如 ;
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)
这是一个使用嵌套拆分方法的想法 例如,首先用 '>' 分割,这将分隔记录,然后用 space " " 分割,这将分隔各个值。 您可以一次进行一个步骤,将所需结果存储在某个变量中 也不要先创建数据框然后附加到它。像这样创建一个以列名作为键的字典
df = {
"Col1 name": [],
"col2 name":[]
}
然后像这样追加到字典中的那个列表
df["Col1 name"].append(value)
你终于可以从这个字典创建数据框了
Csv = pd.DataFrame(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,s,flags=re.M):
scaf,start,_,stop,*rest = match.group().split()
...