在以下数据中,我尝试运行一个简单的马尔可夫模型。
假设我有一个具有以下结构的数据:
pos M1 M2 M3 M4 M5 M6 M7 M8 hybrid_block S1 S2 S3 S4 S5 S6 S7 S8
1 A T T A A G A C A|C C G C T T A G A
2 T G C T G T T G T|A A T A T C A A T
3 C A A C A G T C C|G G A C G C G C G
4 G T G T A T C T G|T C T T T A T C T
block M 表示来自一组类别的数据, block S 也是如此。
数据是strings
这是通过沿位置线连接字母制成的。因此,M1 的字符串值为 A-T-C-G,其他所有 block 也是如此。
还有一个hybrid block
有两个以相同方式读取的字符串。 问题是我想找出混合 block 中的哪个字符串最有可能来自哪个 block (M 与 S)?
我正在尝试构建一个马尔可夫模型,它可以帮助我识别 hybrid block
中的哪个字符串来自哪个街区。在这个例子中,我可以在 hybrid block ATCG
中告诉我来自 block M
和 CAGT
来自 block S
.
我将问题分解成不同的部分以读取和挖掘数据:
问题级别 01:
- 首先,我阅读第一行(标题)并创建
unique keys
对于所有列。 - 然后我读取第二行(
pos
的值为 1)并创建另一个 key 。在同一行中,我从hybrid_block
中读取了值并读取其中的字符串值。pipe |
只是一个分隔符,所以两个字符串在index 0 and 2
中作为A
和C
.所以,我想从这一行中得到一个
defaultdict(<class 'dict'>, {'M1': ['A'], 'M2': ['T'], 'M3': ['T']...., 'hybrid_block': ['A'], ['C']...}
随着我阅读该行的进展,我想附加每列的字符串值并最终创建。
defaultdict(<class 'dict'>, {'M1': ['A', 'T', 'C', 'G'], 'M2': ['T', 'G', 'A', 'T'], 'M3': ['T', 'C', 'A', 'G']...., 'hybrid_block': ['A', 'T', 'C', 'G'], ['C', 'A', 'G', 'T']...}
问题级别 02:
我读取了
hybrid_block
中的数据第一行是A and C
.现在,我想创建
keys' but unlike fixed keys, these key will be generated while reading the data from
混合 block. For the first line since there are no preceding line the
keywill simply be
AgAand
CGCwhich means (A given A, and C given C), and for the values I count the number of
in
M blockand
block S`。因此,数据将存储为:
defaultdict(<class 'dict'>, {'M': {'AgA': [4], 'CgC': [1]}, 'S': {'AgA': 2, 'CgC': 2}}
因为,我通读了其他行我想根据 hybrid block
中的字符串创建新 key 并计算该字符串在 M vs S
中出现的次数 block 给定前一行中的字符串。这意味着 keys
读书时line 2
将是 TgA' which means (T given A) and AgC. For the values inside this key I count the number of times I found
这行中的 T,在上一行中的 A 之后 and same for
AcG`.
defaultdict
阅读 3 行后。
defaultdict(<class 'dict'>, {'M': {'AgA': 4, 'TgA':3, 'CgT':2}, {'CgC': [1], 'AgC':0, 'GgA':0}, 'S': {'AgA': 2, 'TgA':1, 'CgT':0}, {'CgC': 2, 'AgC':2, 'GgA':2}}
我知道这看起来太复杂了。我经历了几个dictionary
和 defaultdict
教程,但找不到执行此操作的方法。
非常感谢对任何部分(如果不是两者)的解决方案。
最佳答案
pandas
设置
from io import StringIO
import pandas as pd
import numpy as np
txt = """pos M1 M2 M3 M4 M5 M6 M7 M8 hybrid_block S1 S2 S3 S4 S5 S6 S7 S8
1 A T T A A G A C A|C C G C T T A G A
2 T G C T G T T G T|A A T A T C A A T
3 C A A C A G T C C|G G A C G C G C G
4 G T G T A T C T G|T C T T T A T C T """
df = pd.read_csv(StringIO(txt), delim_whitespace=True, index_col='pos')
df
解决方案
主要是 pandas
和一些 numpy
- 拆分混合列
- 前置相同的第一行
- 添加 self 的转换版本以获得
'AgA'
类型字符串
d1 = pd.concat([df.loc[[1]].rename(index={1: 0}), df])
d1 = pd.concat([
df.filter(like='M'),
df.hybrid_block.str.split('|', expand=True).rename(columns='H{}'.format),
df.filter(like='S')
], axis=1)
d1 = pd.concat([d1.loc[[1]].rename(index={1: 0}), d1])
d1 = d1.add('g').add(d1.shift()).dropna()
d1
将方便的 block 分配给它们自己的变量名
m = d1.filter(like='M')
s = d1.filter(like='S')
h = d1.filter(like='H')
计算每个 block 中有多少个并连接
mcounts = pd.DataFrame(
(m.values[:, :, None] == h.values[:, None, :]).sum(1),
h.index, h.columns
)
scounts = pd.DataFrame(
(s.values[:, :, None] == h.values[:, None, :]).sum(1),
h.index, h.columns
)
counts = pd.concat([mcounts, scounts], axis=1, keys=['M', 'S'])
counts
如果你真的想要一本字典
d = defaultdict(lambda:defaultdict(list))
dict_df = counts.stack().join(h.stack().rename('condition')).unstack()
for pos, row in dict_df.iterrows():
d['M']['H0'].append((row.loc[('condition', 'H0')], row.loc[('M', 'H0')]))
d['S']['H0'].append((row.loc[('condition', 'H0')], row.loc[('S', 'H0')]))
d['M']['H1'].append((row.loc[('condition', 'H1')], row.loc[('M', 'H1')]))
d['S']['H1'].append((row.loc[('condition', 'H1')], row.loc[('S', 'H1')]))
dict(d)
{'M': defaultdict(list,
{'H0': [('AgA', 4), ('TgA', 3), ('CgT', 2), ('GgC', 1)],
'H1': [('CgC', 1), ('AgC', 0), ('GgA', 0), ('TgG', 1)]}),
'S': defaultdict(list,
{'H0': [('AgA', 2), ('TgA', 1), ('CgT', 0), ('GgC', 0)],
'H1': [('CgC', 2), ('AgC', 2), ('GgA', 2), ('TgG', 3)]})}
关于python - 如何从文件中读取两行并在 for 循环中创建动态键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41929351/