我有这样的输入
A 100
B 150
C 200
D 250
E 300
我想要的输出是上面所有元素的总和:像这样的东西
A to A - 100
A to B - 250
A to C - 450
A to D - 700
A to E - 1000
B to B - 150
B to C - 350
B to D - 600
B to E - 900
C to C - 200
C to D - 450
C to E - 650
D to D - 250
D to E - 550
E to E - 300
文件大小约为250 MB。我写了一个python程序,它首先在字典中存储每行。但我认为这对大型投入来说是不可行的。我是初学者,使用linux。
答案 0 :(得分:1)
这只是存储值和嵌套循环的问题:
awk '
{ label[NR]=$1; val[NR]=$2 }
END {
for (i=1; i<=NR; i++) {
sum = 0
for (j=i; j<=NR; j++) {
sum += val[j]
print label[i] " to " label[j] " - " sum
}
}
}
' file
我认为对于大文件来说这仍然会很慢(你必须将整个文件存储在内存中,并且它是O(N ^ 2)(或者是O(NlogN),它已经有一段时间......)执行嵌套循环的操作。我怀疑将数据丢入数据库可以帮助你。
答案 1 :(得分:1)
所以你的输入文件大约是250MB。我们称之为250MB或262144000字节。您的代表输入是每行7个字节 - 单个字符,两个空格,三位数字和换行符。这意味着大约有3479142个单独的行。
如果你的目的是最终为输入文件中的每一对可能的行生成输出,就像它似乎那样,那么你需要准备好存储3479142 * 37449143/2 = 701219136992653单独的输出行。代表每个代表7个字节,并忽略了大多数可能会更大的事实,即4908533958948571字节,或者您需要存储的4464太字节数据。
希望您的预算有足够的资金支持几个大型EMC阵列。否则,正如你所怀疑的那样,这可能只是在一个不可行的方面......
答案 2 :(得分:0)
使用python:
>>> value =[]
>>> name = []
>>> f=open('yourfile.txt')
>>> for x in f:
... x=x.strip()
... na,va = x.split()
... name.append(na)
... value.append(va)
...
>>> name
['A', 'B', 'C', 'D', 'E']
>>> value
['100', '150', '200', '250', '300']
>>> for i in range(len(name)):
... for j in range(i,len(name)):
... print name[i],name[j],str(sum(map(int,value[i:j+1])))
...
输出:
A A 100
A B 250
A C 450
A D 700
A E 1000
B B 150
B C 350
B D 600
B E 900
C C 200
C D 450
C E 750
D D 250
D E 550
E E 300
答案 3 :(得分:0)
在Python中,您可以使用itertools.combinations_with_replacement
和collections.OrderedDict
执行此操作。这里存储在内存中的唯一东西是一个字典,第一列中的项目作为键,第二列中的项目作为值:
from itertools import combinations_with_replacement
from collections import OrderedDict
with open('file.txt') as f:
data = OrderedDict((k, int(v)) for k, v in (line.split() for line in f))
start = None
tot = 0
for k1, k2 in combinations_with_replacement(data.iterkeys(), 2):
if k1 != start:
start = k1
tot = data[k1]
print '{} to {} - {}'.format(k1, k2, tot)
else:
tot += data[k2]
print '{} to {} - {}'.format(k1, k2, tot)
<强>输出:强>
A to A - 100
A to B - 250
A to C - 450
A to D - 700
A to E - 1000
B to B - 150
B to C - 350
B to D - 600
B to E - 900
C to C - 200
C to D - 450
C to E - 750
D to D - 250
D to E - 550
E to E - 300
答案 4 :(得分:-1)
这是一个快速的:
awk '{s+=$2; printf("%s - %d\n", $1, s)}' <your-file>
如果你想打印A to A, A to B
等,我们将不得不变得更加花哨:
(在tcsh中)
foreach n (`seq 5 -1 1`)
tail -$n <your-file> | awk '{s+=$2; if (a) NR; else{ a=$1;} printf("%s to %s - %d\n", a, $1, s);}'
end
示例输出:
A - 100
B - 250
C - 450
D - 700
E - 1000
B to B - 150
B to C - 350
B to D - 600
B to E - 900
C to C - 200
C to D - 450
C to E - 750
D to D - 250
D to E - 550
E to E - 300