将文件更改为数据框

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()
    ...