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

Posted

技术标签:

【中文标题】如何从文件中读取两行并在 for 循环中创建动态键?【英文标题】:How to read two lines from a file and create dynamics keys in a for-loop? 【发布时间】:2017-06-15 05:21:38 【问题描述】:

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

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

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 

块 M 表示来自一组类别的数据,块 S 也是如此。

数据为strings,由沿位置线连接的字母组成。因此,M1 的字符串值为 A-T-C-G,其他所有块也是如此。

还有一个hybrid block 有两个以相同方式读取的字符串。 问题是我想找出混合块中的哪个字符串最有可能来自哪个块(M vs. S)?

我正在尝试构建一个马尔科夫模型,它可以帮助我识别hybrid block 中的哪个字符串来自哪个块。在这个例子中,我可以看出在混合块ATCG来自block MCAGT来自block S

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

问题级别 01:

首先我阅读第一行(标题)并为所有列创建unique keys。 然后我读取了第二行(pos,值为 1)并创建另一个密钥。在同一行中,我从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 fromhybrid_blocks. For the first line since there are no preceding line thekeyswill simply beAgAandCgCwhich means (A given A, and C given C), and for the values I count the number ofAinblock Mandblock S`。因此,数据将存储为:

defaultdict(<class 'dict'>, 'M': 'AgA': [4], 'CgC': [1], 'S': 'AgA': 2, 'CgC': 2

作为,我通读了其他行,我想根据hybrid block 中的字符串创建新键,并根据前一行中的字符串计算该字符串在M vs S 块中出现的次数。这意味着阅读line 2 时的keys 在这一行中将是TgA' which means (T given A) and AgC. For the values inside this key I count the number of times I foundT,在上一行中的A 之后and same forAcG`。

阅读 3 行后的defaultdict 将是。

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 并将这个文件读取为CSV 文件和space as separator。你会得到DataFrame,它可以轻松访问列-df["M1"]-它可以在没有for循环的情况下做很多事情。 我想知道pandas 但是如何在给定数据上运行markov chain。我已经阅读了pandas,但还没有看到任何可以用来申请的方法(AgA, TgA, CgT)? 【参考方案1】:

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

将方便的块分配给自己的变量名

m = d1.filter(like='M')
s = d1.filter(like='S')
h = d1.filter(like='H')

计算每个块中有多少个并连接

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)])

【讨论】:

感谢您的精彩。你给了我比我预想的更多。由于我的数据结构几乎没有什么不同,因此下游对我来说可能会有一些挑战(会有一些缺失的数据,并且该位置也有一些组)。我正在阅读您的代码并尝试按照pandas, defaultdict 教程和示例来完成我想要的。如果有任何问题,我会与您联系。此外,您还提取了一些我不知道的功能,例如locstack 等。再次感谢。 你能推荐我一些关于 pandas 的高级读物,defaultdict 先生。 @piRSquared。请你看看下面的问题。 ***.com/questions/42012730/… @everestial007 有空我会去看看。我没想到会持续几天。 好的,谢谢。同时,我会尝试看看是否能找到解决部分问题的方法。 是否有在 pandas 中与 groupby 一起执行 applymap 的方法。我试图为此目的找到一个示例或教程,但没有找到。希望你会知道。 ***.com/questions/42150453/… 谢谢!

以上是关于如何从文件中读取两行并在 for 循环中创建动态键?的主要内容,如果未能解决你的问题,请参考以下文章

如何选择每组的前两行并在一列中计算它们之间的差异?

为下一页动态选择行并在剑道网格中反向

如何在不使用 for 循环的情况下从 appsettings 文件中读取对象数组中特定键的值

如何在从列表更新路径的for循环中读取多个json? [复制]

CMD/Batch 从变量中提取每个文本文件行并循环

如何在文本文件中查找行并导出行号