python - 如何从文件中读取两行并在 for 循环中创建动态键?

标签 python pandas numpy dictionary defaultdict

在以下数据中,我尝试运行一个简单的马尔可夫模型。

假设我有一个具有以下结构的数据:

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 MCAGT来自 block S .

我将问题分解成不同的部分以读取和挖掘数据:

问题级别 01:

  • 首先,我阅读第一行(标题)并创建 unique keys对于所有列。
  • 然后我读取第二行(pos 的值为 1)并创建另一个 key 。在同一行中,我从 hybrid_block 中读取了值并读取其中的字符串值。 pipe |只是一个分隔符,所以两个字符串在 index 0 and 2 中作为AC .所以,我想从这一行中得到一个

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 key will simply be AgA and CGCwhich means (A given A, and C given C), and for the values I count the number of in M block and 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}}

我知道这看起来太复杂了。我经历了几个dictionarydefaultdict教程,但找不到执行此操作的方法。

非常感谢对任何部分(如果不是两者)的解决方案。

最佳答案

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

enter image description here

解决方案

主要是 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

enter image description here

将方便的 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

enter image description here

如果你真的想要一本字典

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/

相关文章:

Python:生成具有趋势的随机时间序列数据(例如周期性、指数衰减等)

python - 如何使用空值在 pandas/python 中执行条件语句

python - 无法在 OS X 上将 MySQL 导入到 python 中

python - 将 python 列表操作成我想要的字符串类型

python - pandas如何划分以获得不同两个数据帧的比率

python - 用 pandas reindex 函数填充缺失的数据行

python - 面板数据 - 在 Pandas 中保留至少拥有 3 年数据的公司

python - pandas 通过另一个数据框更新数据框并按列分组

python - 如何使用FastAPI将视频帧和文本返回到HTML页面?

python - 在 NumPy 中使用数组时,resize 和 reshape 之间有什么区别?