Python的map reduce与云计算的map/reduce之间的关系?
我刚开始学习Python,
有人知道Python(还有一些函数式编程语言)里的map()
和reduce()
这两个函数跟分布式计算中的MapReduce概念有什么关系吗?
2 个回答
其实这些概念有点不同,常用的名称可能会让人误解。
在函数式编程中(Python就是从这里借来的这些功能):
map
是把某个函数应用到列表中的所有元素上,然后返回一个新的列表。reduce
是把某个函数用来把列表中的所有值合并成一个单一的值。
而在分布式计算的MapReduce中:
- 我们总是处理键值对(其实就是一对对的东西)。
- mapper 接收一组对,然后生成另一组对(在这个上下文中,输入的“键”不再有特别的意义)。
- reducer 接收一个键和与这个键对应的一组值(来自mapper的输出),然后生成一些键和值的列表(“键”只有在reducer的输入和mapper的输出中才有意义:值会根据键进行分组,然后再传给reducer)。
- 这里你可能还会有分区器和合并器哦 :)
需要注意的是,mapper并不总是为每个输入对生成一个输出对,reducer也不一定会把每个(键,值列表)都减少成一个输出对。mapper和reducer可以输出他们想要的任何东西。例如,mapper可以用来过滤对——在这种情况下,它只为某些输入对生成输出对,而忽略其他的。每个mapper/reducer的输入对也不一定只产生一个输出对(或者有些情况下会产生多个)。
不过在大多数情况下,MapReduce的工作方式和 reduce(reduce_function, map(map_function, list))
是类似的,mapper通常会对每个输入进行一些计算,而reducer通常会以某种方式聚合一组值。对于任何 map_function
和 reduce_function
,都可以用MapReduce来表达,但反过来就不一定了。
云计算中的map/reduce概念很相似,但它是并行工作的。首先,每个数据对象会经过一个函数,这个函数会把它“映射”成一个新的对象(通常是某种字典)。接着,会对map返回的对象对进行一个“归约”操作,直到只剩下一个对象。这就是map/reduce操作的结果。
一个重要的考虑是,由于并行处理,reduce函数必须能够接收来自map函数的对象,以及来自之前reduce函数的对象。当你考虑并行处理的方式时,这就更容易理解了。许多机器会各自把它们的数据减少到一个对象,然后这些对象再被合并成最终的输出。当然,如果数据量很大,这个过程可能会有多个层次。
下面是一个简单的例子,展示你如何使用map/reduce框架来计算一个列表中的单词数量:
list = ['a', 'foo', 'bar', 'foobar', 'foo', 'a', 'bar', 'bar', 'bar', 'bar', 'foo']
list2 = ['b', 'foo', 'foo', 'b', 'a', 'bar']
map函数看起来是这样的:
def wordToDict(word):
return {word: 1}
而reduce函数看起来是这样的:
def countReduce(d1, d2):
out = d1.copy()
for key in d2:
if key in out:
out[key] += d2[key]
else:
out[key] = d2[key]
return out
然后你可以这样进行map/reduce:
reduce(countReduce, map(wordToDict, list + list2))
>>> {'a': 3, 'foobar': 1, 'b': 2, 'bar': 6, 'foo': 5}
但你也可以这样做(这就是并行处理的方式):
reduce(countReduce, [reduce(countReduce, map(wordToDict, list)), reduce(countReduce, map(wordToDict, list2))])
>>> {'a': 3, 'foobar': 1, 'b': 2, 'foo': 5, 'bar': 6}