patternpythonMinor
Case study with a biological populations: a list of lists of lists
Viewed 0 times
casebiologicalstudywithlistslistpopulations
Problem
I have a population (
For example, if on one position on the n-th chromosome, the individuals in the population have the values [3,4,0.4,12,5,6] (that would be a case of a population of 6 individuals).
I'd like to set these value to:
I tried to create this function but I got lost and can hardly find out a solution in all these lists!
You can reach the 14th of the 4th chromosome in the 25th individual by writing:
To make sure my aim is understood. I'd like to create a function which take an instance of
Below is my code (it is long but reading the constructor of the classes
One might have a look to what I tried, the method is called
```
from random import uniform, gauss, choice, expovariate, shuffle
from numpy import arange, array, bincount, ndarray, ones, where
from numpy.random import seed, random, randint, binomial
from opera
Pop) which has an attribute which is a list of individuals (Ind) where each individual has an attribute which is a list of chromosomes (Chromo). Each chromosome is a list of numbers which tells about the fitness (=reproductive success, the fitness is obtain by multiplying all numbers of a all chromosomes) of the individuals. Within one position on the chromosome, there are different values for the different individuals. I'd like to set the greatest value to 1 and the others to keep their relative value in comparison to the biggest value.For example, if on one position on the n-th chromosome, the individuals in the population have the values [3,4,0.4,12,5,6] (that would be a case of a population of 6 individuals).
I'd like to set these value to:
a = [3,4,0.4,12,5,6]
[i/float(max(a)) for i in a]I tried to create this function but I got lost and can hardly find out a solution in all these lists!
You can reach the 14th of the 4th chromosome in the 25th individual by writing:
population.inds[24].chromosomes[3].alleles[13]To make sure my aim is understood. I'd like to create a function which take an instance of
Pop as argument and return the same or another Pop where all positions on the chromosomes are replaced by numbers in the range [0,1] respecting the relative values of all numbers at the same position on the same chromosome in the population.Below is my code (it is long but reading the constructor of the classes
Chromo, Ind and Pop (which are all impressively basic) should, I hope, be enough. The class WalkerRandomSampling serve only the purpose of performing a random weighted sampling).One might have a look to what I tried, the method is called
set_best_fitness_to_one and is within the Pop class.```
from random import uniform, gauss, choice, expovariate, shuffle
from numpy import arange, array, bincount, ndarray, ones, where
from numpy.random import seed, random, randint, binomial
from opera
Solution
Some advice here:
-
Don't repeat yourself. The branches in:
look way too similar. It probably would be better to write :
-
Use list (or set or dict) comprehension whenever you can.
could be written :
and the second line can actually be written differently so that we have :
Similarly :
can be written :
and you could simplify the way you iterate :
And :
could become :
-
Do not build strings using concatenations multiple times. The recommended way is to use
could be written as:
(Also, that will not add the useless
- You should try to follow the PEP 8 guidelines whenever it's possible. In your case, the naming convention is not followed.
- You should try to keep things simple. For instance, in
WalkerRandomSampling.__init__(), it seems like you are doing a bit of logic to handle cases whenkeysis None and cases when it's not but at the end, you never init aWalkerRandomSamplingwith keys so it's quite hard to tell whether this is useful at all.
- Don't repeat yourself. It seems like the beginning of
WalkerRandomSampling.random()is roughly the same no matter ifcount is Noneor not. The common code could be factorised out.
-
Don't repeat yourself. The branches in:
previous_cross = 0
for sex, one_cross in enumerate(cross_pos):
if sex%2 == 0:
recombined_cromo.alleles.append(self.chromosomes.alleles[previous_cross:(one_cross+1)])
else:
recombined_cromo.alleles.append(other.chromosomes.alleles[previous_cross:(one_cross+1)])
previous_cross = one_crosslook way too similar. It probably would be better to write :
previous_cross = 0
for sex, one_cross in enumerate(cross_pos):
relevant_ind = other if sex%2 else self
recombined_cromo.alleles.append(relevant_ind.chromosomes.alleles[previous_cross:(one_cross+1)])
previous_cross = one_cross-
Use list (or set or dict) comprehension whenever you can.
a = []
for i in xrange(10000):
a.append(test.random())
b = []
for value in range(4):
b.append(len([i for i in a if i == value])/float(len(a)))could be written :
a = [test.random() for i in xrange(10000)]
b = [len([value for i in a if i == value])/float(len(a)) for value in range(4)]and the second line can actually be written differently so that we have :
a = [test.random() for i in xrange(10000)]
b = [a.count(value)/float(len(a)) for value in range(4)]Similarly :
alleles = []
for chromo_pos in range(len(self.chromosomes)):
alleles.append(self.chromosomes[chromo.pos].alleles[gene_pos])can be written :
alleles = [self.chromosomes[chromo.pos].alleles[gene_pos] for chromo_pos in range(len(self.chromosomes)]and you could simplify the way you iterate :
alleles = [c.alleles[gene_pos] for c in self.chromosomes]And :
fitness = []
for one_ind in self.inds:
fitness.append(one_ind.fitness())could become :
fitness = [one_ind.fitness() for one_ind in self.inds]-
Do not build strings using concatenations multiple times. The recommended way is to use
join:for ind in xrange(max_pop_size):
first_line += 'fit_ind_' + str(ind) + '\t'could be written as:
first_line += '\t'.join('fit_ind_' + str(ind) for ind in xrange(max_pop_size))(Also, that will not add the useless
\t at the end)Code Snippets
previous_cross = 0
for sex, one_cross in enumerate(cross_pos):
if sex%2 == 0:
recombined_cromo.alleles.append(self.chromosomes.alleles[previous_cross:(one_cross+1)])
else:
recombined_cromo.alleles.append(other.chromosomes.alleles[previous_cross:(one_cross+1)])
previous_cross = one_crossprevious_cross = 0
for sex, one_cross in enumerate(cross_pos):
relevant_ind = other if sex%2 else self
recombined_cromo.alleles.append(relevant_ind.chromosomes.alleles[previous_cross:(one_cross+1)])
previous_cross = one_crossa = []
for i in xrange(10000):
a.append(test.random())
b = []
for value in range(4):
b.append(len([i for i in a if i == value])/float(len(a)))a = [test.random() for i in xrange(10000)]
b = [len([value for i in a if i == value])/float(len(a)) for value in range(4)]a = [test.random() for i in xrange(10000)]
b = [a.count(value)/float(len(a)) for value in range(4)]Context
StackExchange Code Review Q#41821, answer score: 4
Revisions (0)
No revisions yet.