3

我有多个文件,数据写入两列,如下所示:

asp 1.88
gln 3.10
arg 0.99
his 1.11

asp 0.99
gln 1.11
arg 0.08
his 0.01

等等。

我想要做的是将它们添加并写入这样的新文件:

asp 2.87
gln 4.21
arg 1.07
his 1.12

我正在尝试通过导入Counter,但效果不佳。我也试过这样:

inp = ('c"/users/ansm/desktop/xx.txt','r').read().strip().split('\n')
inp2 = ('c"/users/ansm/desktop/xyz.txt','r').read().strip().split('\n')
c = Counter(inp)
d = Counter(inp2)
print c+d

但此代码不会将值相加。

有没有其他方法可以在不使用的情况下做到这一点Counter?我曾经glob.iglob在整个文件夹中迭代具有.txt格式的文件,然后想要处理它们以获得上述结果。使用Counter是最有效的方法还是其他更好的方法?

4

4 回答 4

3

使用此构造创建计数器:

c = Counter(dict((x.split()[0], float(x.split()[1])) for x in inp))
d = Counter(dict((x.split()[0], float(x.split()[1])) for x in inp2))

结果c+d将是:

Counter({'gln': 4.21, 'asp': 2.87, 'his': 1.12, 'arg': 1.07})

编辑许多文件:

s = Counter()
for filename in glob.iglob('*.txt'):
    with open(filename, 'r') as f:
        for line in f:
            k, v = line.split()
            s[k] += float(v)
print s
with open('sum.txt', 'w') as f:
    for k, v in sorted(s.iteritems()):
        f.write('{0} {1}\n'.format(k, v))
于 2012-06-04T11:20:11.837 回答
1

如何使用 defaultdict:

from collections import defaultdict
import glob

d = defaultdict(float)

for filename in glob.iglob('*.txt'):
    with open(filename, "r") as f:
        for line in f:
            k,v = f.split(" ")
            d[k] += float(v)

with open("output.txt", "w") as out:
    for k, v in d.iteritems:
        out.write("%s %f\n" % (k,v))
于 2012-06-04T12:01:35.813 回答
0

这种方法怎么样(Counter不按要求使用):

with open('xx.txt') as f1, open('xyz.txt') as f2, open('result.txt', 'w') as outf:
    for line1 in f1:
        for line2 in f2:
            count = float(line1.split()[-1]) + float(line2.split()[-1])
            outf.write('{:s} {:.2f}\n'.format(line2.split()[0], count))

result.txt包含:

asp 2.87
gln 2.99
arg 1.96
his 1.89

这假设数据包含相同的键并且它们的顺序相同。

with当您完成或发生异常时,使用该构造将自动为您关闭 3 个文件。

于 2012-06-04T11:18:52.993 回答
0

您必须按如下方式在两个计数器中添加每个元素,因为原始计数器存储的是字符串而不是其值的数字(注意float()转换):

r = Counter(c)
for k, v in d.items():
    r[k] += float(v)

现在添加的值在r. c一种更简单的方法是在创建and时直接执行转换d

c = Counter((p[0], float(p[1])) for p in map(lambda s: s.split(), inp))
d = Counter((p[0], float(p[1])) for p in map(lambda s: s.split(), inp2))

现在这将按预期工作:

c + d
> Counter({'gln': 4.21, 'asp': 2.87, 'his': 1.12, 'arg': 1.07})

另请注意,您读取文件的方式并不是最安全的:您打开但从不关闭它们,更好的方法是使用with open,如下所示:

inp = []
with open('c:/users/ansm/desktop/xx.txt', 'r') as input:
    for line in input:
        inp.append(line.strip())
于 2012-06-04T11:22:20.060 回答