使用for循环构建NumPy数组(列表列表?)

时间:2018-10-16 03:17:59

标签: python arrays python-3.x bioinformatics

我正在尝试构建一个数组,其中每行包含来自不同序列的k-mers(k个长度的核苷酸串)。我一直在读,你真的不能有空数组,而且我很难尝试使用append。

bases = ['A', 'T', 'C', 'G']
self.profile = np.array([])

    for x in range(1):
        k = self.ksize
        kmer = [''.join(p) for p in itertools.product(bases, repeat=k)]
        for i in range(0, len(self.motifs)):
            for q in range(0, len(kmer)):
                if kmer[q] in self.motifs[i]:
                    self.kmers.append(kmer[q])
                    self.profile[i] = self.kmers

我在这里遇到的错误是: “ IndexError:索引0超出了尺寸为0的轴0的范围”

我意识到这是因为我没有指定数组的形状,但是我只知道行数,也不知道会有多少列(列大小取决于多少k -mers可在每个序列中找到)。

如果我尝试将其设为“列表列表”:

bases = ['A', 'T', 'C', 'G']
    self.profile = list()

    for x in range(1):
        k = self.ksize
        kmer = [''.join(p) for p in itertools.product(bases, repeat=k)]
        for i in range(0, len(self.motifs)):
            for q in range(0, len(kmer)):
                if kmer[q] in self.motifs[i]:
                    self.kmers.append(kmer[q])
                    self.profile[i] = self.kmers

我得到: self.profile [i] = self.kmers IndexError:列表分配索引超出范围

有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

从评论中收集信息,我认为您想要的是以下内容:给定一个基序列表(在您的情况下,每个长度为50个碱基的核苷酸串),您需要长k的子序列出现在每个。更加Python风格的代码编写方式是:

bases = ['A', 'T', 'C', 'G']
self.profile = []

k = self.ksize
kmer = [''.join(p) for p in itertools.product(bases, repeat=k)]

for mot in self.motifs:
   for km in kmer:
      if km in mot:
         self.kmers.append(km)
         self.profile.append(self.kmers)

请注意,在python中,如果仅用于使用它来访问列表,数组或任何可迭代对象,则不需要遍历索引;您可以循环遍历可迭代本身。检查zipenumerate以获得更大的灵活性。

最后一件事:请注意,self.kmer将是包含[kmer1, kmer2, kmer4, kmer6]的列表,依此类推(例如,您主题中的kmers),但是您将无法区分主题。同样,self.profile将是包含[[kmer1], [kmer1, kmer2], [kmer1, kmer2, kmer4]]的列表的列表,依此类推。

如果您不关心self.profile(因为稍后可以实际构建它),则可以通过大列表理解来做所有事情:

kmers = [km for mot in motifs for km in kmer if km in mot]

编辑:另外两件事

请注意,kmers将具有重复的序列。为了避免这种情况,您可以写一个额外的小记号(if km not in self.kmers,或者使用sets来避免重复。

如果要做想要由主题分隔的kmers列表,则可以通过列表理解以一种更简单的方式完成:

self.profile = [] 
for mot in motifs:
    individual_km = [km for km in kmer if km in mot]
    self.profile.append(individual_km)

答案 1 :(得分:1)

Numpy数组不具备像python列表和字典一样动态增长的能力。如果事实是事实,我上一次阅读是为了随意增加Numpy数组,则将新数组创建为所需的形状,然后从原始数组对象中复制一个副本,但这并不是最佳选择。

要获得所需的结果,我必须先创建一个嵌套列表对象,然后在迭代完成后立即创建所有Numpy数组。只要嵌套列表对象的大小相等,就可以使用类似以下的内容:

my_profile = []

... 您的循环代码 ...

self.profile = np.array(my_profile)