Python 中的 Map&Reduce
Python 中的 Map&Reduce
面对越来越多要处理的数据,我们需要有好的并行算法来帮助我们简化处理流程。并行算法就是一些可同时执行的诸进程的集合,这些进程互相作用和协调动作从而达到给定问题的求解。在这之中分布式算法正在越来越流行。分布式算法,就是指在完成乘加功能时通过将各输入数据每一对应位产生的运算结果预先进行相加形成相应的部分积,然后再对各部分进行累加形成最终结果。
MapReduce就是一种分布式算法的原理,也可以说是一种编程模型。提起map和reduce想必大家并不陌生,map()就是映射函数,而reduce代表的是归并函数。
2003年,MapReduce的诞生标志了超大规模数据处理的第一次革命,而开创这段青铜时代的就是论文《MapReduce: Simplified Data Processing on Large Clusters》,解决了海量数据处理扩展性差的问题。
Google公司2003年提出了一个名为MapReduce的编程模型,用于处理大规模海量数据,并在之后广泛的应用于Google的各项应用中,2006年Apache的Hadoop项目正式将MapReduce纳入到项目中。
如果已经了解过诸如SQL数据库的同学一定觉得数据库对于一些查询之类的操作十分便捷,然而在数据表的行数超过十亿之后处理起来就会非常吃力。MapReduce就可以应用于大规模数据集(大于1TB)的并行运算。
然而我们今天讲的并不是真正的MapReduce,python中内建了map()
和reduce()
函数。
Python 的 map 和 reduce 是Python的内置函数,而 Hadoop 的 MapReduce 是一个计算框架。 两者之间没有直接的关系。但是他们的部分计算操作思想是类似的,其实可以说,MapReduce就是基于map()函数和reduce()函数的
映射函数map()
映射函数接收一个数组,对其中的每个元素都进行相同的处理。
比如我们看下面的例子:
def f(x):
return x * x
r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
这里面我们发现map()中传入两个参数,以一个参数是一个函数,这个函数对后面里表中的每一个数进行操作。如果想要更简单的实现,其实这里也可以采用lambda函数。他之后所跟着的数据要求是可迭代的,经过处理之后也会返回一个可迭代的对象。
map()与直接迭代比较的优势在于
- map()作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单的f(x)=x2,还可以计算任意复杂的函数
- (在Hadoop中)当数据量很大的时候,因为map()是一个分布式算法,可以把大量的工作分配到不同的计算机进行,这样处理的速度会快很多。
- 其实如果换一个方式可以只用一行代码完成上面的过程
list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
需要注意的是,不同长度的多个seq是无法执行map函数的,会出现类型错误。
归并函数reduce()
reduce()可以接受一个键,以及相关的一组值,将这组值进行合并产生一组规模更小的值,通过下面的比较可以直观地看到reduce()究竟做了些什么。
reduce(f, [x1, x2, x3, x4])#使用reduce(),传递进去了一个函数f和一组数
f(f(f(x1, x2), x3), x4)#从头开始分别应用f
我们看到用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,依此类推,最后得到一个结果。下面举例来对一个序列进行求和
from functools import reduce
def add(x, y):
return x + y
reduce(add, [1, 3, 5, 7, 9])
25
参考资料:
- 廖雪峰的Python教程
- 算法图解;人民邮电出版社
- 百度百科:MapReduce