我有一个文件:
1 Chr1 100820415
1 Chr1 100821817
1 Chr1 100821818
1 Chr1 100823536
1 Chr1 100824427
2 Chr1 100824427
2 Chr1 100824427
1 Chr1 100824428
如果所有第2列相同且第3列值相同,我试图添加第1列值。它有点像'聚类'。
所以输出应该是:
1 Chr1 100820415
1 Chr1 100821817
1 Chr1 100821818
1 Chr1 100823536
5 Chr1 100824427
1 Chr1 100824428
我是awk
的新手并尝试理解该语言,但我不能说写一个if $2 is same then add $1 and if $2 is same then add $3 values (if $3 values are same)
的脚本。
这是我到目前为止所尝试的内容:
awk 'BEGIN{ x+=$1 } END {print x} if NF == $2' file_name
解决方案可以在awk
或python
。
答案 0 :(得分:2)
awk
的一种方式:
$ awk '{a[$2 OFS $3]+=$1}END{for(k in a)print a[k],k}' file
1 Chr1 100821817
1 Chr1 100821818
1 Chr1 100820415
5 Chr1 100824427
1 Chr1 100824428
1 Chr1 100823536
python
的一种方式:
$ cat cluster.py
#!/usr/bin/env python
import fileinput
cluster = {}
for line in fileinput.input():
field = line.strip().split()
try:
cluster[' '.join(field[1:])] += int(field[0])
except KeyError:
cluster[' '.join(field[1:])] = int(field[0])
for key, value in cluster.items():
print value, key
使脚本可执行chmod +x cluster.py
并运行如下:
$ ./cluster.py file
1 Chr1 100823536
1 Chr1 100821817
1 Chr1 100820415
5 Chr1 100824427
1 Chr1 100824428
1 Chr1 100821818
这两种方法都利用哈希表来使用相同的技术。使用awk
,我们使用关联数组和python字典。简单地说,两个都是数组,其中键不是数字,而是字符串(第二和第三列值)。一个简单的例子:
blue 1
blue 2
red 5
blue 1
red 2
如果我们说awk '{a[$1]+=$2}' file
,那么我们会得到以下结果:
Line Array Value Explanation
1 a["blue"] 1 # Entry in 'a' is created with key $1 and value $2
2 a["blue"] 3 # Add $2 on line 2 to a["blue"] so the new value is 3
3 a["blue"] 3 # The key $1 is red so a["blue"] does not change
a["red"] 5 # Entry in 'a' is created with new key "red"
4 a["blue"] 4 # Key "blue", Value 1, 1 + 3 = 4
a["red"] 5 # Key "blue", so a["red"] doesn't change
5 a["blue"] 4 # Key "red", so a["blue"] doesn't change
a["red"] 7 # Key "red", Value 2, 5 + 2 = 7
答案 1 :(得分:1)
这样的事情应该有效:
awk '{t1[$2$3] = $2; t2[$2$3] = $3; sums[$2$3] += $1}END{for (s in sums) print sums[s], t1[s], t2[s]}' input.txt
答案 2 :(得分:1)
你想要的是什么:
import re
from collections import defaultdict
d = defaultdict(int)
with open('file.txt') as f:
for line in f:
qty, chr, _id = re.split('\s+', line.strip())
d[(_id, chr)] += int(qty)
for (_id, chr), qty in d.iteritems():
print '{} {} {}'.format(qty, chr, _id)
答案 3 :(得分:0)
这是一个Python版本。
它从stdin读取输入。
注意:它假定第二列始终为Chr1
,并保持输出按最后一列的值排序 - 它不会保留输入的顺序。
#!/usr/bin/env python2.7
import sys
# Maps a 'value' to its count
counter = {}
for line in sys.stdin:
num, tag, value = line.split()
num = int(num)
counter[value] = counter.setdefault(value, 0) + num
for value in sorted(counter.keys()):
print counter[value], 'Chr1', value