Python的map reduce与云计算的map/reduce之间的关系?

6 投票
2 回答
637 浏览
提问于 2025-04-17 06:16

我刚开始学习Python,

有人知道Python(还有一些函数式编程语言)里的map()reduce()这两个函数跟分布式计算中的MapReduce概念有什么关系吗?

2 个回答

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_functionreduce_function,都可以用MapReduce来表达,但反过来就不一定了。

8

云计算中的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}

撰写回答