Построить массив NumPy с циклом for (список списков?)

1

Я пытаюсь построить массив, где каждая строка содержит 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: индекс назначения списка вне диапазона

Есть лучший способ сделать это?

  • 1
    Просто обратите внимание: диапазон начинается по умолчанию с 0, поэтому reange(0, len(kmer)) точно такой же, как и range(len(kamer)) .
  • 0
    Не совсем понятно, что вы хотите архивировать. Ваш код, представленный здесь, не воспроизводит ошибку, потому что, по-видимому, у вас нет определенного класса. Взгляните на минимальный воспроизводимый пример . В self.profile случае, если массивы, которые вы self.profile в self.profile , не имеют одинаковую длину, numpy - это не то, что вам нужно: [ stackoverflow.com/questions/3386259/… .
Показать ещё 6 комментариев
Теги:
arrays
python-3.x
bioinformatics

2 ответа

1
Лучший ответ

Собирая информацию из комментариев, я думаю, что вы хотите следующее: учитывая список мотивов (в вашем случае, нуклеотидные строки длиной 50 байт), вы хотите, чтобы подпоследовательности (k-mers) длины k, которые появлялись в каждый. Чем больше pythonic способ написать ваш код будет:

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 вам не нужно перебирать индексы, если вы собираетесь использовать их для доступа к спискам, массивам или любым итерабельным; вы можете просто перебирать итерируемый себя. Проверьте zip и enumerate для большей гибкости.

Еще одна вещь: обратите внимание, что self.kmer будет списком, [kmer1, kmer2, kmer4, kmer6] и т.д. (Т. Е. Ксеры в мотиве), но вы не сможете различать мотивы. Кроме того, self.profile будет списком списков, содержащих [[kmer1], [kmer1, kmer2], [kmer1, kmer2, kmer4]] и т.д.

Если вы не заботитесь о self.profile (потому что вы можете его построить позже), вы можете сделать все с большим пониманием списка:

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

EDIT: две дополнительные вещи

Обратите внимание, что таким образом, kmers будут иметь повторяющиеся последовательности. Чтобы избежать этого, вы можете либо написать дополнительный чек (if km not in self.kmers), а, скорее, использовать наборы, чтобы избежать повторения.

Если вам нужен список сортировщиков, разделенных мотивами, вы можете сделать это более простым способом со списком:

self.profile = [] 
for mot in motifs:
    individual_km = [km for km in kmer if km in mot]
    self.profile.append(individual_km)
  • 0
    Как бы я написал это так, чтобы я мог сделать весь этот процесс, как: В первом нуклеотиде self.motifs найдите k-mers, сохраните k-mers в списке, поместите этот список в другой список .... и затем выполните этот процесс снова для следующей строки нуклеотидов в self.motifs-- добавляя каждый список по пути? Таким образом, мои данные соответствуют (т.е. self.motifs [0] идет с self.kmers [0], который идет с self.profile [0])?
  • 1
    Если я правильно понимаю ваш вопрос, см. Отредактированный ответ. Однако я не уверен, что вы хотите, чтобы self.profile содержал.
Показать ещё 6 комментариев
1

Массивные массивы не очень удобны для динамического роста, как списки и словари python. Если факт, который я прочитал, чтобы произвольно вырастить массивы Numpy, новый массив создается в желаемой форме, а затем копия создается из исходного объекта массива, что не слишком оптимально.

Чтобы достичь результатов, которые вам нужны, мне сначала нужно создать вложенные объекты списка, а затем создать массив Numpy сразу после завершения итераций. Поскольку размер вложенных объектов списка равен, вы можете просто использовать что-то вроде:

my_profile = []

... ваш код цикла...

self.profile = np.array(my_profile)

  • 1
    Измените это «self.profile [i] = self.kmers» на self.profile.append (self.kmers) при работе со списками

Ещё вопросы

Сообщество Overcoder
Наверх
Меню