在Map reduce Python中统计文件以及日期

时间:2014-02-01 22:12:01

标签: python split mapreduce mapper reducers

我有一个映射器,它给我一些像

这样的词
apple 10 12012013
apple 20 12022013
apple 30 12042013
apple 40 12032013

其中第一个值是单词,然后在第3列中提到的那一天出现该单词。

我写了一个减速器,它可以选择密钥作为苹果,然后得到它的总数。

所以输出就像这样

apple 100

但我需要输出as,

100 apple 12012013:10 12022013:20 12032013:30 12042013:40 

知道我应该如何修改我的映射器?

我在Amazon EMR Hadoop Streaming上运行此Map reduce作业。

编辑:以下代码完美无缺,但我得到的输出为:

4   apple   20130601
:1  20130602
:1  20130601
:1  20130602
:1  

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

这应该这样做:

>>> with open('filename') as f:
    dic = {}
    for line in f:
        name, quan, dt = line.split()
        dic.setdefault(name, []).append((dt, quan))
...         

>>> for k, v in dic.items():
    total = sum(int(x[1]) for x in v)
    print '{} {} {}'.format(total, k, ' '.join('{}:{}'.format(x, y) for x, y in v))
...     
100 apple 12012013:10 12022013:20 12042013:30 12032013:40

如果具有相同产品的数据始终组合在一起,您也可以使用itertools.groupby

>>> from itertools import groupby
>>> with open('abc1') as f:
    for k, g in groupby(f, key=lambda x:x.split()[0]):
        data = [x.split()[1:] for x in g]
        total = sum(int(x[0]) for x in data)
        print '{} {} {}'.format(total, k, ' '.join('{}:{}'.format(y, x) for x, y in data))
...         
100 apple 12012013:10 12022013:20 12042013:30 12032013:40

<强>更新

如果输入来自文件流,那么您可以使用sys.stdin

import sys
from itertools import groupby
for k, g in groupby(sys.stdin, key=lambda x:x.split()[0]):
    ...