如何通过删除列表中的特定元素来 运行 给定列表的 itertools 产品?

How to run the itertools product for the given list by removing a specific element in the list?

在以下数据集中 (mcve_01.txt):

mcve_01.txt

pos         M1     M2      F1_x     F1_y    Sk1     S2    Sj
16230484    G/G   G/G       G       T        T/T    T/T   T/T
16230491    C/C   C/C       C       T        T/T    .     T/T
16230503    T/T   T/T       T       T        T/T    .     T/T
16230524    T/T   T/T       T       A        A/A    A/A   A/A
16230535    .     .         T       C        .      .       .
16232072    A/A   A/A       A       G        G/G    G/G   G/G
16232072    A/A   A/A       A       G        G/G    G/G   G/G
16229783    C/C   C/C       G       C        G/C    G/C   C|G
16229992    A/A   A/A       G       A        A/A    A/A   A|G
16230007    T/T   T/T       A       T        A|T    A|T   A|T
16230011    G/G   G/G       C       G        C|G    C|G   G/C
16230049    A/A   A/A       T       A        .      A/T   A/T
16230174    .      .        T       C        T|C    T|C   C|T
16230190    A/A   A/A       T       A        G|T    T|G   T|G
16230260    A/A   A/A       G       A        G/G    G/G   G/G
16230260    A/A   A/A       G       A        G/G    G/G   G/G
16232772    A/A   A/A       C       A        C/C    C/C   C/C
16232793    C/C   C/C       T       C        T/T    T/T   T/T
16232793    C/C   C/C       T       C        T/T    T/T   T/T
16232282    T/T   T/T       T       A        A/A    A/A   A/A

我正在尝试 运行 马尔可夫模型。

下面是我的代码:

import pandas as pd
import itertools as it

mcve_data = pd.read_csv('mcve_01.txt', sep='\t')

mcve_data.set_index(['pos'], inplace = True)

mcve_list = mcve_data.applymap(lambda c:[list(c)])

注意: 我必须将每列中的值转换为列表,以便我可以 运行 所需的 itertools.product 或压缩,具体取决于条件。

def mapfun(c):
    cstr = ''.join(map(str, c))
    if '.' in cstr:
        return '.'

    if '/' in cstr:
        sep = '/'
        fun = it.product

    else:
        sep = '|'
        fun = zip

    return ','.join('g'.join(t) for t in fun(*c) if sep not in t)

现在(下),应用该函数进行马尔可夫建模。

mcve_mm = (mcve_list+mcve_list.shift(1)).dropna(how='all').\
applymap(mapfun)

注意:因此,在上面的代码中,(mcve_list+mcve_list.shift(1)) 从同一列的两行读取值以应用马尔可夫链。

print(mcve_mm)

pd.DataFrame.to_csv(mcve_mm, 'mcve_mm.txt', sep='\t', index=True)

输出(mcve_mm.txt)为:

    pos     M1          M2          F1_x    F1_y    Sk1             S2              Sj
16230491    CgG,CgG,CgG,CgG     CgG,CgG,CgG,CgG     CgG TgT TgT,TgT,TgT,TgT         .               TgT,TgT,TgT,TgT
16230503    TgC,TgC,TgC,TgC     TgC,TgC,TgC,TgC     TgC TgT TgT,TgT,TgT,TgT         .               TgT,TgT,TgT,TgT
16230524    TgT,TgT,TgT,TgT     TgT,TgT,TgT,TgT     TgT AgT AgT,AgT,AgT,AgT         .               AgT,AgT,AgT,AgT
16230535    .           .           TgT CgA .               .               .
16232072    .           .           AgT GgC .               .               .
16232072    AgA,AgA,AgA,AgA     AgA,AgA,AgA,AgA     AgA GgG GgG,GgG,GgG,GgG         GgG,GgG,GgG,GgG         GgG,GgG,GgG,GgG
16229783    CgA,CgA,CgA,CgA     CgA,CgA,CgA,CgA     GgA CgG GgG,GgG,CgG,CgG         GgG,GgG,CgG,CgG         CgG,CgG,|gG,|gG,GgG,GgG
16229992    AgC,AgC,AgC,AgC     AgC,AgC,AgC,AgC     GgG AgC AgG,AgC,AgG,AgC         AgG,AgC,AgG,AgC         AgC,GgG
16230007    TgA,TgA,TgA,TgA     TgA,TgA,TgA,TgA     AgG TgA AgA,AgA,|gA,|gA,TgA,TgA     AgA,AgA,|gA,|gA,TgA,TgA     AgA,TgG
16230011    GgT,GgT,GgT,GgT     GgT,GgT,GgT,GgT     CgA GgT CgA,GgT CgA,GgT         GgA,Gg|,GgT,CgA,Cg|,CgT
16230049    AgG,AgG,AgG,AgG     AgG,AgG,AgG,AgG     TgC AgG .               AgC,Ag|,AgG,TgC,Tg|,TgG     AgG,AgC,TgG,TgC
16230174    .           .           TgT CgA .               TgA,TgT,|gA,|gT,CgA,CgT     CgA,CgT,|gA,|gT,TgA,TgT
16230190    .           .           TgT AgC GgT,TgC             TgT,GgC             TgC,GgT
16230260    AgA,AgA,AgA,AgA     AgA,AgA,AgA,AgA     GgT AgA GgG,Gg|,GgT,GgG,Gg|,GgT     GgT,Gg|,GgG,GgT,Gg|,GgG     GgT,Gg|,GgG,GgT,Gg|,GgG
16230260    AgA,AgA,AgA,AgA     AgA,AgA,AgA,AgA     GgG AgA GgG,GgG,GgG,GgG         GgG,GgG,GgG,GgG         GgG,GgG,GgG,GgG
16232772    AgA,AgA,AgA,AgA     AgA,AgA,AgA,AgA     CgG AgA CgG,CgG,CgG,CgG         CgG,CgG,CgG,CgG         CgG,CgG,CgG,CgG
16232793    CgA,CgA,CgA,CgA     CgA,CgA,CgA,CgA     TgC CgA TgC,TgC,TgC,TgC         TgC,TgC,TgC,TgC         TgC,TgC,TgC,TgC
16232793    CgC,CgC,CgC,CgC     CgC,CgC,CgC,CgC     TgT CgC TgT,TgT,TgT,TgT         TgT,TgT,TgT,TgT         TgT,TgT,TgT,TgT
16232282    TgC,TgC,TgC,TgC     TgC,TgC,TgC,TgC     TgT AgC AgT,AgT,AgT,AgT         AgT,AgT,AgT,AgT         AgT,AgT,AgT,AgT

因此,输出文件中有几个时髦的输出。 类似于第 16230260 行中的 GgG,Gg|,GgT,GgG,Gg|,GgT

我正在努力摆脱这类问题。

问题在于代码:

    if '/' in cstr:
        sep = '/'
        fun = it.product

当 c(列表)是这样的:

    if '/' in cstr:
        print(c)
        print(type(c))
        sep = '/'
        fun = it.product

一些 c(由于移位而从两行读取)具有以下结构我认为这是问题所在

[['C', '|', 'G'], ['G', '/', 'G']]

<class 'list'>

因此,it.product 将竖线 (|) 与另一个列表中的其余元素相乘。

试过了:

if '/' in cstr:
    for x in c:
       while '|' in x:
            x.remove('|')  

# but I think this is not updating c but sometimes affecting the c in other columns by borrowing the condition met from previous line.

    sep = '/'
    fun = it.product

我也试过了:

    for x in c:
       while '|' in x:
            c == list(''.join(x).strip('|') for x in c)

把列表转成字符串然后去掉竖线(|)再转回列表,但是运行报错

所以,问题是: 如果 c 中有管道(|),当 运行ning it.product for lines/c like:

[['C', '|', 'G'], ['G', '/', 'G']]

<class 'list'>

以下类型的 c 的预期输出:

[['C', '|', 'G'], ['G', '/', 'G']][['C', '/', 'G'], ['G', '/', 'G']]

相同:CgG, CgG, GgG, GgG

我建议按如下方式更改功能:

from itertools import product
from functools import partial

def mapfun(c):
    if any(['.' in l for l in c]):
        return '.'

    if all(['|' in l for l in c]):
        fun = zip
    else:
        fun = product

    return ','.join('g'.join(t) for t in fun(*map(mapfun.filt,c)))

mapfun.filt_set = set(['|','/'])
mapfun.filt = partial(filter,lambda l: not (l in mapfun.filt_set))

print(mapfun([['C', '|', 'G'], ['G', '|', 'G']]))
print(mapfun([['C', '/', 'G'], ['G', '/', 'G']]))
print(mapfun([['C', '|', 'G'], ['G', '/', 'G']]))
print(mapfun([['C', '/', 'G'], ['G', '|', 'G']]))

这会产生输出:

CgG,GgG
CgG,CgG,GgG,GgG
CgG,CgG,GgG,GgG
CgG,CgG,GgG,GgG

zip 用于第一个示例,itertools.product 用于以下所有示例。

解释:

  • 要确定任何条件(“.”出现在任何参数中或“|”出现在所有参数中)是否为真,使用列表理解:例如 ['.' in l for l in c] 是一个布尔值列表当且仅当相应的参数包含一个点时才为真。然后 any 用于检查是否有任何参数包含 '.'.
  • 变量 filt 是在 mapfun 之外定义的,因此不必在每次调用 mapfun 时重新计算它 - 注意污染名称 space 它被添加为函数对象的一个​​属性(参见What is the Python equivalent of static variables inside a function?
  • 注意 partial(filter, f) 等同于 lambda x: filter(f,x)
  • partial 中的 lambda 仅检查元素是否在 filt_set 中,因此应将其删除
  • *map(mapfun.filt,c) 简单地使用 mapfun.filt 过滤所有参数,然后将它们作为参数传递给所选函数 f