python hadoop流中的组合函数

时间:2010-11-24 16:53:36

标签: python hadoop mapreduce

我有一个输出键和值的映射器,它被排序并通过管道输入reducer.py,

由于键已经排序,在我到达reducer之前,我想编写一个组合器,它遍历排序列表并输出将在reducer中使用的键,[v1,v2,v3]对。

cat数据| python mapper.py |排序| python reducer.py

编写reducer的最佳机制是什么,这样我就不会使用包含所有键的字典,大量的内存来保存字典中的条目。

1 个答案:

答案 0 :(得分:4)

使用itertools.groupby

>>> import itertools
>>> import operator
>>> foo = [("a", 1), ("a", 2), ("b", 1), ("c", 1), ("c", 2)]
>>> for group in itertools.groupby(foo, operator.itemgetter(0)):
...     print group[0], list(map(operator.itemgetter(1), group[1]))
...
a [1, 2]
b [1]
c [1, 2]

说明:

groupby,顾名思义,基于某些关键函数将迭代的元素分组为块。也就是说,它在iterable的第一个元素上调用keyfunc,然后从迭代中逐个拉取元素,直到keyfunc的值发生变化,此时它会生成它已经获得的所有元素到目前为止,从新密钥开始。它也是明智的,不会消耗超过必要的内存;一旦产生价值,它们就不再由groupby持有。

在这里,我们按operator.itemgetter(0)对输入元素进行分组,这是一个有用的“工具箱”功能,可将x映射到x[0]。换句话说,我们按元组的第一个元素进行分组,这是一个键。

当然,您需要编写一个自定义生成器来处理读取输入(可能来自sys.stdin)并逐个生成它们。幸运的是,使用yield关键字非常简单。

另请注意,这假定键已排序。当然,如果它们没有排序,那么你无能为力:你需要查看输入的结尾,以确保你拥有给定键的所有值。