从打印输出中获取 table (pandas)
Get a table from a print output (pandas)
我 运行 在 python 包 ete3 中实现了一个名为 codeml 的程序。
这是 codeml 生成的模型的打印:
>>> print(model)
Evolutionary Model fb.cluster_03502:
log likelihood : -35570.938479
number of parameters : 23
sites inference : None
sites classes : None
branches :
mark: #0 , omega: None , node_ids: 8 , name: ROOT
mark: #1 , omega: 789.5325 , node_ids: 9 , name: EDGE
mark: #2 , omega: 0.005 , node_ids: 4 , name: Sp1
mark: #3 , omega: 0.0109 , node_ids: 6 , name: Seq1
mark: #4 , omega: 0.0064 , node_ids: 5 , name: Sp2
mark: #5 , omega: 865.5116 , node_ids: 10 , name: EDGE
mark: #6 , omega: 0.005 , node_ids: 7 , name: Seq2
mark: #7 , omega: 0.0038 , node_ids: 11 , name: EDGE
mark: #8 , omega: 0.067 , node_ids: 2 , name: Sp3
mark: #9 , omega: 999.0 , node_ids: 12 , name: EDGE
mark: #10 , omega: 0.1165 , node_ids: 3 , name: Sp4
mark: #11 , omega: 0.1178 , node_ids: 1 , name: Sp5
但由于它只是印刷品,我需要将这些信息放入 table,例如:
Omega node_ids name
None 8 ROOT
789.5325 9 EDGE
0.005 4 Sp1
0.0109 6 Seq1
0.0064 5 Sp2
865.5116 10 EDGE
0.005 7 Sp3
0.0038 11 EDGE
0.067 2 Sp3
999.0 12 EDGE
0.1165 3 Sp4
0.1178 1 Sp5
因为我需要解析这些信息。
您知道如何处理打印输出吗?
感谢您的帮助。
你的问题中隐含的假设有两个问题:
为什么要打印?
为什么首先要打印模型?这不是以编程方式访问模型内部的好方法,因为这是供人类阅读的,并且您无法确定模型的某些信息是否在其 __str__()
方法中被遗漏,该方法用于印刷。你必须找出 Evolutionary Model
的结构,将这个结构变成一个字典,然后使用 pandas.DataFrame.from_dict 从这个字典创建一个数据框,我会说。
先看看 model.__dict__()
和 model.__repr__()
。
如果你能看一下定义Evolutionary Model
的代码,你当然可以直接查找Evolutionary Model
的结构并把它变成字典。
为什么是数据框?
如果您只是想 "parse" 模型,那么如果您只是想以编程方式访问其属性,将其放入数据框中需要做很多额外的工作。只需直接访问属性,例如 model.branches
如果您想获取模型的 branches
属性的值。
我看了一下underlying code in model.py
看来你可以使用s = model.__str__()
来获取这个打印输出的字符串。从那里您可以使用标准字符串操作解析字符串。我不知道您的字符串的确切形式,但您的代码可能如下所示:
import pandas as pd
lines = s.split('\n')
lst = []
first_idx = 6 # Skip the lines that are not of interest.
names = [field[:field.index(':')].strip() for field in lines[first_idx].split(',')]
for line in lines[first_idx:]:
if line:
row = [field[field.index(':')+1:].strip().strip("#") for field in line.split(',')]
lst.append(row)
df = pd.DataFrame(lst, columns=names)
有更漂亮的方法可以做到这一点,但它可以完成工作。
您可以使用 StringIO
和 applymap
from io import StringIO
import pandas as pd
df = pd.read_csv(StringIO(model.__repr__()), skiprows=6, names=['mark', 'omega', 'node_ids', 'name'])
df = df.applymap(lambda x: x.split(":")[1])
输出:
mark omega node_ids name
0 #0 None 8 ROOT
1 #1 789.5325 9 EDGE
2 #2 0.005 4 Sp1
3 #3 0.0109 6 Seq1
4 #4 0.0064 5 Sp2
5 #5 865.5116 10 EDGE
6 #6 0.005 7 Seq2
7 #7 0.0038 11 EDGE
8 #8 0.067 2 Sp3
9 #9 999.0 12 EDGE
10 #10 0.1165 3 Sp4
11 #11 0.1178 1 Sp5
我 运行 在 python 包 ete3 中实现了一个名为 codeml 的程序。
这是 codeml 生成的模型的打印:
>>> print(model)
Evolutionary Model fb.cluster_03502:
log likelihood : -35570.938479
number of parameters : 23
sites inference : None
sites classes : None
branches :
mark: #0 , omega: None , node_ids: 8 , name: ROOT
mark: #1 , omega: 789.5325 , node_ids: 9 , name: EDGE
mark: #2 , omega: 0.005 , node_ids: 4 , name: Sp1
mark: #3 , omega: 0.0109 , node_ids: 6 , name: Seq1
mark: #4 , omega: 0.0064 , node_ids: 5 , name: Sp2
mark: #5 , omega: 865.5116 , node_ids: 10 , name: EDGE
mark: #6 , omega: 0.005 , node_ids: 7 , name: Seq2
mark: #7 , omega: 0.0038 , node_ids: 11 , name: EDGE
mark: #8 , omega: 0.067 , node_ids: 2 , name: Sp3
mark: #9 , omega: 999.0 , node_ids: 12 , name: EDGE
mark: #10 , omega: 0.1165 , node_ids: 3 , name: Sp4
mark: #11 , omega: 0.1178 , node_ids: 1 , name: Sp5
但由于它只是印刷品,我需要将这些信息放入 table,例如:
Omega node_ids name
None 8 ROOT
789.5325 9 EDGE
0.005 4 Sp1
0.0109 6 Seq1
0.0064 5 Sp2
865.5116 10 EDGE
0.005 7 Sp3
0.0038 11 EDGE
0.067 2 Sp3
999.0 12 EDGE
0.1165 3 Sp4
0.1178 1 Sp5
因为我需要解析这些信息。
您知道如何处理打印输出吗?
感谢您的帮助。
你的问题中隐含的假设有两个问题:
为什么要打印?
为什么首先要打印模型?这不是以编程方式访问模型内部的好方法,因为这是供人类阅读的,并且您无法确定模型的某些信息是否在其 __str__()
方法中被遗漏,该方法用于印刷。你必须找出 Evolutionary Model
的结构,将这个结构变成一个字典,然后使用 pandas.DataFrame.from_dict 从这个字典创建一个数据框,我会说。
先看看 model.__dict__()
和 model.__repr__()
。
如果你能看一下定义Evolutionary Model
的代码,你当然可以直接查找Evolutionary Model
的结构并把它变成字典。
为什么是数据框?
如果您只是想 "parse" 模型,那么如果您只是想以编程方式访问其属性,将其放入数据框中需要做很多额外的工作。只需直接访问属性,例如 model.branches
如果您想获取模型的 branches
属性的值。
我看了一下underlying code in model.py
看来你可以使用s = model.__str__()
来获取这个打印输出的字符串。从那里您可以使用标准字符串操作解析字符串。我不知道您的字符串的确切形式,但您的代码可能如下所示:
import pandas as pd
lines = s.split('\n')
lst = []
first_idx = 6 # Skip the lines that are not of interest.
names = [field[:field.index(':')].strip() for field in lines[first_idx].split(',')]
for line in lines[first_idx:]:
if line:
row = [field[field.index(':')+1:].strip().strip("#") for field in line.split(',')]
lst.append(row)
df = pd.DataFrame(lst, columns=names)
有更漂亮的方法可以做到这一点,但它可以完成工作。
您可以使用 StringIO
和 applymap
from io import StringIO
import pandas as pd
df = pd.read_csv(StringIO(model.__repr__()), skiprows=6, names=['mark', 'omega', 'node_ids', 'name'])
df = df.applymap(lambda x: x.split(":")[1])
输出:
mark omega node_ids name
0 #0 None 8 ROOT
1 #1 789.5325 9 EDGE
2 #2 0.005 4 Sp1
3 #3 0.0109 6 Seq1
4 #4 0.0064 5 Sp2
5 #5 865.5116 10 EDGE
6 #6 0.005 7 Seq2
7 #7 0.0038 11 EDGE
8 #8 0.067 2 Sp3
9 #9 999.0 12 EDGE
10 #10 0.1165 3 Sp4
11 #11 0.1178 1 Sp5