python map reduce和云计算map/reduce之间的关系?

python map reduce和云计算map/reduce之间的关系?,python,cloud,mapreduce,Python,Cloud,Mapreduce,我是Python新手 有人知道Python(和函数语言)函数map()/reduce()和与分布式计算相关的MapReduce概念之间的关系吗?map/reduce的云概念非常相似,但改为并行工作。首先,每个数据对象通过一个函数传递,该函数将其映射到一个新对象(通常是某种字典)。然后,对map返回的对象对调用reduce函数,直到只剩下一个对象为止。这是map/reduce操作的结果 一个重要的考虑因素是,由于并行化,reduce函数必须能够接收map函数中的对象以及先前reduce函数中的对象

我是Python新手


有人知道Python(和函数语言)函数
map()
/
reduce()
和与分布式计算相关的MapReduce概念之间的关系吗?

map/reduce的云概念非常相似,但改为并行工作。首先,每个数据对象通过一个函数传递,该函数将其映射到一个新对象(通常是某种字典)。然后,对
map
返回的对象对调用
reduce
函数,直到只剩下一个对象为止。这是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}
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 
reduce(countReduce, map(wordToDict, list + list2))

>>> {'a': 3, 'foobar': 1, 'b': 2, 'bar': 6, 'foo': 5}
reduce函数如下所示:

def wordToDict(word):
  return {word: 1}
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 
reduce(countReduce, map(wordToDict, list + list2))

>>> {'a': 3, 'foobar': 1, 'b': 2, 'bar': 6, 'foo': 5}
然后您可以像这样映射/减少:

def wordToDict(word):
  return {word: 1}
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 
reduce(countReduce, map(wordToDict, list + list2))

>>> {'a': 3, 'foobar': 1, 'b': 2, 'bar': 6, 'foo': 5}
但您也可以这样做(这就是并行化的作用):


事实上,这些概念有些不同,常用的名称有误导性

在函数式编程中(Python借用了这些函数):

  • map
    将某些函数应用于列表的所有元素并返回新列表
  • reduce
    应用一些函数来聚合某个列表中的所有值以获得单个值
在分布式计算MapReduce中:

  • 我们总是使用键值对(好的,只是对)
  • 映射器获取一个对列表并生成另一个对列表(“输入键”在此上下文中失去其语义)
  • reducer获取与此键对应的键和值列表(来自映射器输出),并生成一些键和值列表(“键”具有键语义的单个位置是reducer输入/映射器输出:值在传递到reducer之前按键分组)
  • 您还可以在此处使用分区器和合并器:)
请注意,无论是映射器始终为每个输入对生成一个输出对,还是reducer始终都不会将每个(键、值列表)减少到恰好一个输出对。Mapper和reducer可以输出他们想要的任何内容。例如,映射器可用于过滤对-在这种情况下,它为某些输入对生成输出对,而忽略其他输入对。对于每个mapper/reducer输入对(或其中的一些输入对),产生多个对也是很常见的


但在大多数情况下,MapReduce的工作方式与
reduce(reduce_函数,map(map_函数,list))
-mapper通常对每个输入进行一些计算,reducer通常以某种方式聚合一个值列表。对于任何
map\u函数
reduce\u函数
,都可以用MapReduce来表示,但反之亦然。

最后一个示例是否应该或可以在子列表上显式递归调用(即在子列表上映射
lambda l:reduce(countReduce,map(wordToDict,*)
)@AndrewJaffe不确定我是否理解你的评论。你能详细说明一下吗?
[reduce(countReduce,map(wordToDict,list)),reduce(countReduce,map(wordToDict,list2))
map(lambda l:reduce(countReduce,map(wordToDict,l)),[list1,list2]相同
我认为这更好地体现了操作的精神。@AndrewJaffe这并不是做同样的事情。你需要用另一个reduce来包装它,所以它开始变得非常混乱。我会坚持我的,因为我认为这更明显。