Map Reduce简单评分聚合常见查询

时间:2013-02-25 08:04:18

标签: python algorithm mapreduce

我的一个mapper会生成一些分布在文件中的日志,例如part-0,part-1,part-2等。现在每个日志都有一些查询和该查询的一些相关数据:

part-0

q             score         
1 ben 10      4.01
horse shoe    5.96
...

part-1

1 ben 10        3.23
horse shoe      2.98
....

and so on for part-2,3 etc.

现在相同的查询q,即上面的“1本10”,位于第1部分,第2部分等。

现在我必须编写一个地图缩减阶段,我可以在其中收集相同的查询并汇总(加起来)他们的分数。

我的映射器功能可以是一个标识,在reduce中我将完成此任务。

输出将是:

q       aggScore
1 ben 10    7.24
horse shoe  8.96
...

似乎是一项简单的任务,但我无法想到如何进行此操作(阅读很多但不能继续)。我可以考虑通用算法问题,其中首先我将收集常见的查询,然后加上他们的分数。

任何有关pythonic解决方案或算法(map reduce)提示的帮助都会非常感激。

1 个答案:

答案 0 :(得分:1)

这是MapReduce解决方案:

地图输入:每个输入文件(第0部分,第1部分,第2部分......)可以输入到单独的(单独的)地图任务中。

输入文件中的foreach输入行, Mapper会发出<q,aggScore>。如果单个文件中的查询有多个分数,Map会将它们全部加起来,否则如果我们知道每个查询只会出现在每个文件中一次,则map可以是每个输入发出<q,aggScore>的标识函数按原样排列。

Reducer输入的格式为<q,list<aggScore1,aggScore2,...>。Reducer操作类似于wordcount的着名MapReduce示例。如果您使用的是Hadoop,则可以使用以下方法进行Reducer。

public void reduce(Text q, Iterable<IntWritable> aggScore, Context context) throws IOException, InterruptedException {
   int sum = 0;
   for (IntWritable val : aggScore) {
      sum += val.get();
   }
   context.write(q, new IntWritable(sum));
}

该方法将对特定aggScores的所有q求和,并为您提供所需的输出。 reducer的python代码应如下所示(这里q是键,aggScores的列表是值):

def reduce(self, key, values, output, reporter):
    sum = 0
    while values.hasNext():
        sum += values.next().get()
    output.collect(key, IntWritable(sum))