【问题标题】:Access every character in a list of strings avoiding nested for loops访问字符串列表中的每个字符,避免嵌套 for 循环
【发布时间】:2014-03-04 06:38:11
【问题描述】:

我目前正在处理一些 DNA 序列数据,我需要为每个站点创建一个频率矩阵。例如,像这样:

A   T   G   C
0.2 0.3 0.3 0.2
0.3 0.4 0.1 0.2
0.7 0.1 0.1 0.1

输入是许多DNA序列的列表,例如:

te_seqs = ["ATCTACTGATG", "ATACAGTACATAGA", "ATAGACAGTTGTGCG", "GTCGATACGT", ...]

每个序列都有数千个字符长,并且有数千个序列。输出是一个 numpy 矩阵,其中包含每个站点的频率计数。比如上面的数据,第一个站点有3个A和1个G,所以A的频率是3/4=0.75,G的频率是1/4=0.25。 T和C的频率都是0。

我目前有一个我所有序列的列表,我通过将 1 添加到 Nx4 矩阵来获得频率。问题是我正在处理大量序列并且嵌套的 for 循环在时间上并不理想:

for seq in te_seqs:
    for i,nuc in enumerate(seq):
        if nuc == "A":
            te_pwm[i, 0] = te_pwm[i, 0] + 1 
        elif nuc == "T":
            te_pwm[i, 1] = te_pwm[i, 1] + 1
        elif nuc == "G":
            te_pwm[i, 2] = te_pwm[i, 2] + 1
        elif nuc == "C":
            te_pwm[i, 3] = te_pwm[i, 3] + 1

for seq in gene_seqs:
    for i,nuc in enumerate(seq):
        if nuc == "A":
            gene_pwm[i, 0] = gene_pwm[i, 0] + 1 
        elif nuc == "T":
            gene_pwm[i, 1] = gene_pwm[i, 1] + 1
        elif nuc == "G":
            gene_pwm[i, 2] = gene_pwm[i, 2] + 1
        elif nuc == "C":
            gene_pwm[i, 3] = gene_pwm[i, 3] + 1

我的问题是 1) 是否有一种更 Pythonic 的方式来检查 stings 列表中的每个字符串? 2) 有没有更好的方法来创建基频矩阵?

谢谢!

【问题讨论】:

  • 能否提供一些测试数据?
  • 是的,我正在使用来自这里的数据:maizetedb.org/cgi-bin/cgiwrap/maize/TE_search.cgi。单击 II 类并下载该数据。这里有更多信息:nbviewer.ipython.org/gist/arundurvasula/9338256 但这篇文章尚未完成
  • 你能用示例输入和输出解释你的程序吗?现在还不清楚。
  • 我添加了更多解释。矩阵的边是序列(站点)中的每个位置。那有意义吗?我可以根据需要进行更多编辑。
  • 谢谢 :) 但是,site 是什么?我相信这是一条重要的信息。

标签: python for-loop numpy


【解决方案1】:

您可以使用itertools.izip_longest() 遍历站点,然后使用collections.Counter 进行计数:

import collections
import itertools

te_seqs = ["ATCTACTGATG", "ATACAGTACATAGA", "ATAGACAGTTGTGCG", "GTCGATACGT"]

sites = map(collections.Counter, itertools.izip_longest(*te_seqs))
for site in sites:
  A = site.get("A", 0)
  T = site.get("T", 0)
  G = site.get("G", 0)
  C = site.get("C", 0)
  total = float(A + T + G + C)
  print A / total, T / total, G / total, C / total

这会产生

0.75 0.0 0.25 0.0
0.0 1.0 0.0 0.0
0.5 0.0 0.0 0.5
0.0 0.25 0.5 0.25
1.0 0.0 0.0 0.0
0.0 0.25 0.25 0.5
0.5 0.5 0.0 0.0
...

【讨论】:

  • 谢谢!我稍微修改了解决方案以适应将频率添加到 numpy 数组,但这很好用。再次感谢!
猜你喜欢
  • 1970-01-01
  • 2020-05-26
  • 2016-01-23
  • 2012-06-25
  • 2016-05-31
  • 2022-12-15
  • 1970-01-01
  • 1970-01-01
  • 2017-08-27
相关资源
最近更新 更多