python - 如何在Python列表中对许多类别组合(72个变量)进行分类

标签 python

我将数据存储在如下组织的列表列表中:

lst = [
      ['FHControl', G, A]
      ['MNHDosed', G, C]
      ]

对于 lst: row[0] 中的行,总共有 12 个类别(我在上面的示例代码中列出了两个类别)。对于 row[1] 和 row[2] 我只关心这些字母的 6 个组合。因此,我在 lst 中每行有 72 种可能的数据组合,并且需要计算每个组合的实例,而不必编写数十个嵌套 if 循环。

我正在尝试创建两个函数来解析这些列表并对这 72 种组合的发生率进行分类。我如何使用两个像我下面开始写的函数来更新这些变量?我是否需要将字典构造为类变量,以便在迭代这两个函数时可以继续更新它们?任何指导都会很棒!

这是我当前的代码,它将所有 72 个变量初始化为 6 个字典(针对 row[1] 和 row[2] 中的 6 种字母组合):

def baseparser(lst):
    TEMP = dict.fromkeys('FHDosed FHControl FNHDosed FNHControl '
                         'FTDosed FTControl MHDosed MHControl '
                         'MNHDosed MNHControl MTDosed MTControl'.split(), 0)
    TRI_1, TRI_2, TRV_1, TRV_2, TRV_3, TRV_4 = ([dict(TEMP) for i in range(6)])

    for row in lst:
        if row[0] == 'FHDosed':
            binner(row[0], row[1], row[2])
        if row[0] == 'FHControl':
            binner(row[0], row[1], row[2])
        etc.

def binner(key, q, s):
    if (q == 'G' and s == 'A') or (q =='C' and s =='T'):
        TRI_1[key] += 1
    elif (q == 'A' and s == 'G') or (q =='T' and s =='C'):
        TRI_2[key] += 1
    elif (q == 'G' and s == 'T') or (q =='C' and s =='A'):
        TRV_1[key] += 1
    elif (q == 'G' and s == 'C') or (q =='C' and s =='G'):
        TRV_1[key] += 1
    elif (q == 'A' and s == 'T') or (q =='T' and s =='A'):
        TRV_1[key] += 1
    elif (q == 'A' and s == 'C') or (q =='T' and s =='G'):
        TRV_1[key] += 1

最佳答案

您的代码可以简化为:

TEMP = dict.fromkeys('''FHDosed FHControl FNHDosed FNHControl FTDosed FTControl MHDosed 
                      MHControl MNHDosed MNHControl MTDosed MTControl'''.split(), 0)
TRI_1, TRI_2, TRV_1, TRV_2, TRV_3, TRV_4 = [TEMP.copy() for i in range(6)]

dmap = {
    ('G', 'A'): TRI_1,
    ('C', 'T'): TRI_1,
    ('A', 'G'): TRI_2,
    ('T', 'C'): TRI_2,        
    ('G', 'C'): TRV_1,
    ('C', 'G'): TRV_1,        
    ('A', 'T'): TRV_1,
    ('T', 'A'): TRV_1,        
    }

for row in lst:
    key, q, s = row
    dmap[q, s][key] += 1

另一种可能性是使用一个字典中的字典而不是 6 个字典:

TEMP = dict.fromkeys('''FHDosed FHControl FNHDosed FNHControl FTDosed FTControl MHDosed 
                      MHControl MNHDosed MNHControl MTDosed MTControl'''.split(), 0)
TR = {key:TEMP.copy() for key in ('TRI_1', 'TRI_2', 'TRV_1', 'TRV_2', 'TRV_3', 'TRV_4')}


dmap = {
    ('G', 'A'): 'TRI_1',
    ('C', 'T'): 'TRI_1',
    ('A', 'G'): 'TRI_2',
    ('T', 'C'): 'TRI_2', 
    ('G', 'C'): 'TRV_1',
    ('C', 'G'): 'TRV_1', 
    ('A', 'T'): 'TRV_1',
    ('T', 'A'): 'TRV_1',        
    }

lst = [
      ['FHControl', 'G', 'A'],
      ['MNHDosed', 'G', 'C']
      ]

for row in lst:
    key, q, s = row
    TR[dmap[q, s]][key] += 1

print(TR)

这样做的好处是你的命名空间中的字典更少,并且以后使用字典的字典而不是硬编码 6 个字典可能更容易重构代码。


跟进午夜者的建议,如果你有 pandas ,您可以用 DataFrame 替换 dicts 的 dicts。然后可以使用 pd.crosstabs 计算配对的频率。像这样:

import pandas as pd

dmap = {
    'GA': 'TRI_1',
    'CT': 'TRI_1',
    'AG': 'TRI_2',
    'TC': 'TRI_2', 
    'GC': 'TRV_1',
    'CG': 'TRV_1', 
    'AT': 'TRV_1',
    'TA': 'TRV_1',        
    }

lst = [
      ['FHControl', 'G', 'A'],
      ['MNHDosed', 'G', 'C']
      ]

df = pd.DataFrame(lst, columns=['key', 'q', 's'])
df['tr'] = (df['q']+df['s']).map(dmap)

print(df)
#          key  q  s     tr
# 0  FHControl  G  A  TRI_1
# 1   MNHDosed  G  C  TRV_1

print(pd.crosstab(rows=[df['key']], cols=[df['tr']]))

产量

tr         TRI_1  TRV_1
key                    
FHControl      1      0
MNHDosed       0      1

关于python - 如何在Python列表中对许多类别组合(72个变量)进行分类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24459767/

相关文章:

c# - 具有完整子结构的矩阵的 "Matrix decomposition"

python - Scrapy:如何在蜘蛛中使用项目以及如何将项目发送到管道?

python - 如何在 pythonanywhere 上安装 GNU MPFR 库

python - 将包含类别的列与包含整数的列合并

python - 如何从字典中选择多行(executemany select)

python - Pyramid :自定义 404 页面返回为 "200 OK"

python - 在单元测试中创建后可以更新用户对象的属性吗?

Python 2.7 在列表列表中查找最小值、最大值

Python函数指针

python - 如何使一个变量等于一个字符串 - Python