我有一个像这样的字符串列表:
('aatt')
('aaga')
('aaac')
('gtag')
#the real list have thousands of strings
最佳的期望结果是表格分隔文件,如下所示:
0 1 2 3
a:75% a:75% a:50% a:25%
g:25% t:25% g:25% c:25%
t:25% g:25%
t:25%
(标题不是必需的)
我做了一个bash脚本来做,但现在我正在学习python,我想用它做。
这是我的bash代码:
#!/bin/bash
for i in $(echo 1 2 3 4)
do echo $i && cat FILE | grep N -v | awk -F "" '{print $'$i'}' | awk -f ./WC
done
其中WC是以下wordcounter:
BEGIN {
FS="[^a-zA-Z]+"
}
{
for (i=1; i<=NF; i++)
words[toupper($i)]++
}
END {
for (i in words)
print i, words[i]
}
答案 0 :(得分:3)
在这里得到一些严厉的评论,但我会尝试给你一些指示:)从你的数据的外观看起来你似乎正在尝试SNP呼吁你有一个序列表?鉴于此类数据:
d = ['aatt','aaga','aaac','gtag']
您应该做的第一件事是预先分配一个字典,用于存储每个位置的字母数。我假设你只有4个字母,即a,t,c和g,你知道字符串的最大长度。如果你不这样做,你可以这样提取它:
maxLen = max(map(len,l))
完成后,创建字典:
freqDict = dict([(i,{'a':0.0,'t':0.0,'c':0.0,'g':0.0}) for i in xrange(maxLen)])
然后存储每个位置的字母数:
for s in l:
for i,b in enumerate(s):
freqDict[i][b] += 1
这应该导致:
In [26]: freqDict
Out[26]:
{0: {'a': 3.0, 'c': 0.0, 'g': 1.0, 't': 0.0},
1: {'a': 3.0, 'c': 0.0, 'g': 0.0, 't': 1.0},
2: {'a': 2.0, 'c': 0.0, 'g': 1.0, 't': 1.0},
3: {'a': 1.0, 'c': 1.0, 'g': 1.0, 't': 1.0}}
从那时起,您可以根据自己的需要打印结果。每行一个位置打印结果可能更有效率,因此您不必迭代整个位置列表4次,即
for i in freqDict:
vs = freqDict[i]
sumvs = sum(vs.values())
print '%d\t%s' % (i,'\t'.join(['%s:%.1f' % (b[0],b[1]*100/sumvs) for b in vs.items()]))
生成:
0 a:75.0 c:0.0 t:0.0 g:25.0
1 a:75.0 c:0.0 t:25.0 g:0.0
2 a:50.0 c:0.0 t:25.0 g:25.0
3 a:25.0 c:25.0 t:25.0 g:25.0