Как связать два зависимых ввода неизвестного размера с переменными
Это мой первый скрипт на python. Мои данные выглядят так:
Position ind1 ind2 ind3 ind4 ind5 ind5 ind7 ind8
0 C A C A A A A A
1 C A C C C A A A
но он может варьироваться по количеству столбцов и имеет тысячи строк.
Мой сценарий, который делает то, что мне нужно, читает этот файл построчно и вычисляет частоту A и C для комбинации людей (в дальнейшем население) в каждой позиции (POS). Например, частота А в положении 0 для населения 1 (ind1, ind2, ind3, ind4); и частота А в положении 0 для населения 2 (ind5, ind6, ind7, ind8), то же самое для POS 1, 2, 3 ....
Для этого я определяю комбинацию столбцов (совокупностей) в моем скрипте следующим кодом:
alleles1 = alleles[1:5]
alleles2 = alleles[5:]
но если у меня более 9 столбцов и различные комбинации столбцов, мне нужно изменить аллели * и остальную часть сценария после этого.
Я хочу сделать мою программу более интерактивной, чтобы пользователь определял количество популяций и определял, какой столбец соответствует какому населению.
Код у меня так далеко:
#ask for the number of populations
try:
num_pop = int(raw_input("How many populations do you have? > "))
except ValueError:
print "In is not an integer! \nThe program exits...\n "
#ask for individuals in population
ind_pop = {}
for i in range(num_pop):
i += 1
ind_input = str(raw_input("Type column numbers of population %i > " % i))
ind_pop[i] = re.findall(r'[^,;\s]+', ind_input)
если у меня 2 популяции, где столбцы 3, 5, 6 - это население 1, а столбцы 2, 5 - это население 2. Это работает следующим образом:
> How many populations do you have? > 2
> Type column numbers of population 1 > 3, 5, 6
> Type column numbers of population 2 > 2, 4
Входные данные хранятся в словаре.
{1: ['3', '5', '6'], 2: ['2', '4']}
Вопрос в том, как перейти от этого ввода к определению аллелей. Вывод должен быть таким:
allele1 = [allele[3], allele[5], allele[6]]
allele2 = [allele[2], allele[4]]
Если это необходимо, вот основные части остальной части кода:
with open('test_file.txt') as datafile:
next(datafile)
for line in datafile:
words = line.split() #splits string into the list of words
chr_pos = words[0:2] #select column chromosome and position
alleles = words[2:] # this and next separates alleles for populations
alleles1 = alleles[0:4]
alleles2 = alleles[4:8]
alleles3 = alleles[8:12]
alleles4 = alleles[12:16]
counter1=collections.Counter(alleles1)
counter2=collections.Counter(alleles1)
counter3=collections.Counter(alleles1)
counter4=collections.Counter(alleles1)
#### the rest of the code and some filters within the part above were spiked
3 ответа
Сначала нужно преобразовать номера столбцов в целые числа
ind_pop[i] = [int(j) for j in re.findall(r'[^,;\s]+', ind_input)]
(Я бы также изменил ваше регулярное выражение на r'\d+'
)
Тогда вместо того, чтобы alleles1
, alleles2
и т.д., иметь основной список или словарь:
master = {i: [alleles[j] for j in vals] for i, vals in ind_pop.items()}
counters = {i: collections.Counter(al) for i, al in master.items()}
Тогда вы можете получить доступ counters[i]
вместо counter1
и т.п.
Как примечание, вы, вероятно, можете упростить все вышеперечисленное, сделав ind_pop
в список, используя append
вместо того чтобы держать счетчик
Спасибо за предложения. Некоторые из них были полезны. Я чувствую, что мне нужно изменить направление. Я буду продолжать работать со списком списка:
pop_alleles = []
for key in ind_pop.keys():
pop_alleles.append([alleles[el] for el in ind_pop[key]])
Если это выход, который вы ищете,
allele1 = [allele[3], allele[5], allele[6]]
allele2 = [allele[2], allele[4]]
и у вас есть это:
{1: ['3', '5', '6'], 2: ['2', '4']}
это довольно просто отсюда.
for index in population_dict[1]:
allele1.append(allele[index])
for index in population_dict[2]:
allele2.append(allele[index])
О, если индексы хранятся в виде строк, так как они выглядят так, как если бы они были выше, вам сначала нужно сделать их целочисленными. Вы можете изменить вышеприведенное на аллель [int(index)], но было бы лучше просто превратить их в целые, когда вы их читаете.