A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

    在hadoop中最重要的就是基于hdfs的MapReduce分布式计算模型(以下简称“MR模型”)。hadoop周边的框架都是基于MapReduce做的各种操作,因此MapReduce是学好hadoop的基础。但是,很多初学者对Map、Reduce的本来面目不了解,一时之间不明白map、reduce到底是干什么的,为什么这个样子。下文试图逐一详解。

    Map、Reduce是两个函数,属于函数式编程语言中的固有函数。我们java属于面向对象语言,与函数式编程语言有很大区别。以下就以python为例讲述:

  
a=[1,2,3,4,5]
m = map(
lambda x:x+3, a)
list(m)
#[4, 5, 6, 7, 8]
  

    以上4条语句是用python写的。我现在逐一讲述每条语句。
    第一句是定义一个list,包含5个元素,赋值给一个变量a(python声明时不需要指定数据类型)。
    第二句是关键。其中蓝色的“lambda”是关键词,用于定义一个匿名函数。该匿名函数的形式参数是x,函数定义是返回x+3.那么“lambda x:x+3”就是定义一个匿名函数,形式参数是x,返回x+3。就这么简单。简单的理解为java中new一个接口就行了。好了,继续分析。这里的map就是一个函数。map函数包括两个参数,第一个就是刚才定义的匿名函数,第二个是一个a,即第一句中定义的list。map函数执行后,把返回值赋值给变量m。
    第三句是显示语句,使用list函数显示上面的运算结果m的值。
    第四句是显示第三句的运行结果。我们发现,map函数结果也是一个list,并且list中包含的元素个数与参数a的元素个数相同,但是m中的每个元素都是a中对应元素执行匿名函数的结果。
    以上就是python写的四句代码的全部含义。大家不要纠结python的语法,只需要关注map的含义即可。

  总结Mapper的含义是对输入的列表中的每一个元素执行一个函数,生成一个列表结果。运算前后列表的元素数量不变化

    我们在写MR模型时,覆盖Mapper类的map方法时,map函数的每个输入就是外部文件的每一行啊。这正是上面例子中map函数体现的要点。

    下面来看reduce函数的本来面目,还是以python代码为例:


import functools
a = [1,2,3,4,5]
s = functools.reduce(lambda x,y:x+y,a)
print(s)               
#15                                    
  

    以上一共包含5行python代码。
    第一行是导入类库。
    第二行是声明一个列表,包含5个元素,赋值给一个变量a。
    第三行是关键。首先看到一个匿名函数“lambda x,y:x+y”。该函数两个形式参数x和y。方法体是x+y。函数reduce的参数有两个,第一个是上面讲的匿名函数,第二个是列表a。运算后赋值给变量s。
    第四行是打印s。
    第五行是显示结果15.
    从以上例子可以看到,15是列表a执行匿名函数的结果。

    总结Reduce的含义就是“Reduce是对输入的列表中的所有元素执行一个函数操作,并将中间结果作为参数继续执行函数”。

    好像还是没理解吧?继续向下看Reduce的深度分析。

    Reduce中匿名函数的两个形参是x和y(假设默认值都是0),这个匿名函数在运行时传入的参数是a中的各个元素。其中x分别是1,2,3,4,5;那么y会传入什么值哪?y是x+y的累计值。

    一步步的遍历a中的元素,过程如下:
    1.x、y默认值都是 0
    2.当x=1,y=0时,运算完成后x+y,即1+0,等于1;
    3.当x=2,y=1时,运算完成后x+y,即2+1,等于3;
    4.当x=3,y=3时,运算完成后x+y,即3+3,等于6;
    5.当x=4,y=6时,运算完成后x+y,即4+6,等于10;
    6.当x=5,y=10时,运算完成后x+y,即5+10,等于15;

    可能会感觉到reduce的用法这么奇怪,因为python是函数式编程语言。函数语言中函数是一等公民,就像java中类一样普遍。

    python中的map、reduce函数会分别遍历参数a中的每一个元素,有点类似于java中的for循环,不必扣细节,大体理解就可以。举例子的目的就是为了让大家有个大致了解,方便以后的hadoop学习。

    同学们,理解map、reduce函数的本质了吗?不明白的,请留言吧

41 个回复

正序浏览
可否这样理解:
int[] src={1,2,3,4,5};//五个元素
int[]result=new int[5];//和上面保持一致;
for(int i=0;i<src.length;i++){
result[i]=function(src[i]);
}对mapper的理解;
就是这两句话:列表中的每一个元素执行一个函数-----列表中的所有元素执行一个函数
这两句话有什么区别吗?
回复 使用道具 举报
老师辛苦啦啊啊
回复 使用道具 举报
过来学习科普知识
回复 使用道具 举报
王广智 发表于 2013-4-5 21:01
我语言表述错误,老师,是他们都是函数,没有他们是一个函数的意思,看来以后语言应该注意防止二义性。 ...

经过你这一解释,我忽然看懂了你表达的意思。哈哈。

我在写短信、qq聊天、写文章等的时候,每句话都斟酌多次,看是否理解有歧义,自己觉得有问题的时候删掉重写。这纯属自己习惯,和你无关啊,呵呵
回复 使用道具 举报
没看懂哎郁闷
回复 使用道具 举报
吴超老师 发表于 2013-4-4 20:55
我哪段文字给你留下这个印象了,罪过啊

mapper和reducer是两个不同的函数。看入参就知道了。 ...

我语言表述错误,老师,是他们都是函数,没有他们是一个函数的意思,看来以后语言应该注意防止二义性。
回复 使用道具 举报
吴超老师 发表于 2013-4-5 05:44
兄弟神勇,工作中一定是黑马一匹。

在python中增加map、reduce函数就是为了替代这种大段代码的。其他语 ...

小生年逾弱冠,正打算这次去云三呢,还要多向老师请教!
回复 使用道具 举报
杜鹏飞 发表于 2013-4-4 22:32
前几天看到同事买了一本书,讲的就是Hadoop,厚的吓死人,于是乎没怎么去了解。刚刚看到了老师的这篇文章, ...

兄弟神勇,工作中一定是黑马一匹。

在python中增加map、reduce函数就是为了替代这种大段代码的。其他语言也能类似实现,代码越多,可维护越差。二者相较,优劣立显
回复 使用道具 举报
额,智商拙计了,一直在想怎么用泛型for来实现这个特性,其实简单地记录一个变量就可以了。
  1. function reduce(f,list)
  2.         function list_table(list)
  3.                 local iter = 0
  4.                 local len = table.getn(list)
  5.                 return function()
  6.                         iter = iter+1
  7.                         if iter <= len then return list[iter] end
  8.                 end
  9.         end

  10.         local ret = {}
  11.         local sum = 0
  12.         for ele in list_table(list) do
  13.                 sum = f(sum,ele)
  14.                 table.insert(ret,sum)
  15.         end
  16.         return ret
  17. end
复制代码

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1 偶然发现,必须鼓励~ 话说你怎么还是10分以.

查看全部评分

回复 使用道具 举报
本帖最后由 杜鹏飞 于 2013-4-4 23:00 编辑

前几天看到同事买了一本书,讲的就是Hadoop,厚的吓死人,于是乎没怎么去了解。刚刚看到了老师的这篇文章,写的不错,百度了一下发现map和reduce似乎是
python固有的函数,而且reduce的兰博德表达式只支持传递两个参数,老师一开始没指明,害我苦思reduce的实现很久,这是后话了。本人未学习过python,故打算
用lua实现下这两个函数。map很简单:
  1. function map(f,list)
  2.         function list_table(list)
  3.                 local iter = 0
  4.                 local len = table.getn(list)
  5.                 return function()
  6.                         iter = iter+1
  7.                         if iter <= len then return list[iter] end
  8.                 end
  9.         end


  10.         local ret={}
  11.         for ele in list_table(list) do
  12.                 table.insert(ret,f(ele))
  13.         end
  14.         return ret
  15. end
复制代码
我采用了迭代器+泛型for的形式,python好像支持泛型for(函数式程序设计语言好像都支持T_T)
接下来写reduce,reduce的一般形式是容易实现的,但是,我忽然想到了一个东西,那就是如果让reduce去返回一个中间值的表,会如何呢?见程序:
  1. function reduce(f,list)
  2.         function list_table(list)
  3.                 local iter = 0
  4.                 local len = table.getn(list)
  5.                 return function()
  6.                         iter = iter+1
  7.                         if iter <= len then return list[iter] end
  8.                 end
  9.         end

  10.         local ret={}
  11.         for ele in list_table(list) do
  12.                 if table.getn(ret) == 0 --问题在此!
  13.                 then table.insert(ret,ele)
  14.                 else table.insert(ret,f(ret[table.getn(ret)],ele)) end
  15.         end
  16.         return ret
  17. end
复制代码
我的这种写法做了O(n)次无谓的判断!我认为应该有更优秀的写法,能深刻利用泛型for的特点或巧妙地赋值来避免无谓的测试,如能指点,不胜感激。
回复 使用道具 举报
王广智 发表于 2013-4-4 20:44
也就是mapper和reduce都是一个函数啊,执行的结果不同。

:funk:我哪段文字给你留下这个印象了,罪过啊

mapper和reducer是两个不同的函数。看入参就知道了。
回复 使用道具 举报
也就是mapper和reduce都是一个函数啊,执行的结果不同。
回复 使用道具 举报
吴超老师 发表于 2013-4-4 19:42
说个真实的例子,在传智最近刚毕业的一个学生,专门应聘hadoop职位,只会安装hadoop、hbase,收到了两份of ...

老师你这么一说,我就有信心了。 现在才刚开始学习linux,为hadoop做准备。
回复 使用道具 举报
老师讲得浅显易懂啊!
回复 使用道具 举报
本帖最后由 吴超老师 于 2013-4-4 19:45 编辑
蔡兆军 发表于 2013-4-4 19:36
老师,3天的课程学习到的知识,能去应聘hadoop方面的工作吗??

说个真实的例子,在传智最近刚毕业的一个学生,专门应聘hadoop职位,只会安装hadoop、hbase,收到了两份offer。一份是一家纳斯达克上市的互联网公司,一家是小公司,6.5K。他寻求更高的职位,目前还没入职。

更多的例子通过javaEE找到工作的。刚进入公司,就要求学习hadoop。这些的例子太多了,都发生在刚毕业的这几个班。

通过三天的学习,你绝不是仅仅安装hadoop、hbase的水平的。
回复 使用道具 举报
老师,3天的课程学习到的知识,能去应聘hadoop方面的工作吗??
回复 使用道具 举报
顶一个:):D;P
回复 使用道具 举报
准备学,先备着
回复 使用道具 举报
哈哈,谢谢分享啦!!!
回复 使用道具 举报
吴超老师 发表于 2013-4-4 18:05
你说的“打包处理”,我不清楚什么意思。另外,你说的“映射数”,是不是我所说的“函数”,我也不确定。
...

呵呵,学习了,学习了,黑马的课程还是一如既往的好。
回复 使用道具 举报
123下一页
您需要登录后才可以回帖 登录 | 加入黑马