这是我的第一个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
但它可能在多列中有所不同,并且有数千行。
我做我需要的脚本逐行读取此文件,并计算每个位置(POS)中个人(以下称人口)组合的A和C的频率。例如,对于种群1(ind1,ind2,ind3,ind4),位置0处的A的频率;对于人口2(ind5,ind6,ind7,ind8)的位置0的A和频率,然后对于POS1,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
答案 0 :(得分:2)
首先需要将列号转换为整数
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
而不是保留计数器来简化上述所有操作
答案 1 :(得分:0)
如果这是您正在寻找的输出,
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。您可以将上面的内容更改为allele [int(index)],但是当您阅读它们时,最好将它们设置为整数。
答案 2 :(得分:0)
感谢您的建议。其中一些是有用的。我觉得我需要改变方向。我将继续使用列表清单:
pop_alleles = []
for key in ind_pop.keys():
pop_alleles.append([alleles[el] for el in ind_pop[key]])