python版MapReduce基础实战

2023-05-16

第一关:成绩统计

任务描述

本关任务:使用Map/Reduce计算班级中年龄最大的学生。

相关知识

为了完成本关任务,你需要掌握:1.什么是MapReduce,2.如何使用MapReduce进行运算。

什么是MapReduce

MapReduce是一种可用于数据处理的编程模型,我们现在设想一个场景,你接到一个任务,任务是:挖掘分析我国气象中心近年来的数据日志,该数据日志大小有3T,让你分析计算出每一年的最高气温,如果你现在只有一台计算机,如何处理呢?我想你应该会读取这些数据,并且将读取到的数据与目前的最大气温值进行比较。比较完所有的数据之后就可以得出最高气温了。不过以我们的经验都知道要处理这么多数据肯定是非常耗时的。

如果我现在给你三台机器,你会如何处理呢?看到下图你应该想到了:最好的处理方式是将这些数据切分成三块,然后分别计算处理这些数据(Map),处理完毕之后发送到一台机器上进行合并(merge),再计算合并之后的数据,归纳(reduce)并输出。

这就是一个比较完整的MapReduce的过程了。

 

如何使用MapReduce进行运算

我们通过一个示例,来体验Map/Reduce的使用。

我们从一个问题入手:目前我们想统计两个文本文件中,每个单词出现的次数。

首先我们在当前目录下创建两个文件:

创建file01输入内容:


  
  1. mkdir input
  2. echo "Hello World Bye World" >> input/file01
  3. cat input/file01

创建file02输入内容:


  
  1. touch file02
  2. echo "Hello Hadoop Goodbye Hadoop" >> input/file02
  3. cat input/file02

编写文件mapper.pyreducer.py


  
  1. vim mapper.py

输入字母i,进入编辑状态,输入以下内容:


  
  1. #! /usr/bin/python3
  2. import sys
  3. def main():
  4. # 从标准输入流中接受数据行,对每一行调用mapper函数来处理
  5. for line in sys.stdin:
  6. line = line.strip()
  7. mapper(line)
  8. # 每行分割为一个个单词,用word表示
  9. # hadoop streaming要求用"键\t值"形式输出键值对
  10. def mapper(line):
  11. words = line.split(' ')
  12. for word in words:
  13. if len(word.strip()) == 0:
  14. continue
  15. print("%s\t%s" % (word, 1))
  16. if __name__ == '__main__':
  17. main()

保存文件并退出编辑 1.敲“ESC”键,编辑状态; 2.输入冒号“:”然后输入小写字母"wq",并敲回车键,就可以保存文件并返回命令行了。

继续用上面的方法编写文件reducer.py,内容如下:


  
  1. #! /usr/bin/python3
  2. import sys
  3. from operator import itemgetter
  4. # 对values求和,并按"单词\t词频"的形式输出。
  5. def reducer(k, values):
  6. print("%s\t%s" % (k, sum(values)))
  7. def main():
  8. current_key = None
  9. values = []
  10. _key, _value = '', 0
  11. for line in sys.stdin:
  12. line = line.strip()
  13. _key, _value = line.split('\t', 1)
  14. _value = eval(_value)
  15. if current_key == _key:
  16. values.append(_value)
  17. else:
  18. if current_key:
  19. reducer(current_key, values)
  20. values = []
  21. values.append(_value)
  22. current_key = _key
  23. # 不要忘记最后一个键值对
  24. if current_key == _key:
  25. reducer(current_key, values)
  26. if __name__ == '__main__':
  27. main()

保存并退出。

调试程序

hadoop-streaming可以在本地调试运行,也可以在hadoop集群上运行。一般在本地调试通过后在放到集群运行。

本地调试

在命令行输入以下命令即可在本地调试:

 


  
  1. cat input/file* |python3 mapper.py |sort -k1,1|python3 reducer.py

其中cat是显示文件内容; sort -k1,1完成maprduce的排序功能,表示对内容按照第一列排序。

 

集群调试

接下来在hadoop集群上运行次程序:


  
  1. # 启动hadoop集群:start-all.sh
  2. # 在集群上创建文件夹,并上传数据文件至集群
  3. hadoop fs -mkdir /user/test
  4. hadoop fs -mkdir /user/test/input
  5. hadoop fs -put input/file01 /user/test/input
  6. hadoop fs -put input/file02 /user/test/input
  7. # 删除目标目录
  8. hadoop fs -rm -r /user/test/output
  9. # 执行程序,以下10-15行是一条命令,\是命令的换行符,应该一起输入。
  10. hadoop jar \
  11. /usr/local/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.7.4.jar \
  12. -mapper mapper.py \
  13. -reducer reducer.py \
  14. -input /user/test/input/ \
  15. -output /user/test/output > log.txt
  16. # 查看生成的文件
  17. hadoop fs -ls /user/test/output
  18. # 如果程序运行成功,应该生成_SUCCESS和part-00000两个文件,第一个表示运行成功,第二个就是生成的输出。
  19. #可以使用cat命令查看:
  20. hadoop fs -cat /user/test/output/part-00000
  21. # 如果没有得到正确结果或没有生成输出文件,可以通过log.txt来查错:
  22. cat log.txt | more
  23. # 最后删除上传的文件和生成的结果
  24. hadoop fs -rm -r /user/test/input
  25. hadoop fs -rm -r /user/test/output

代码解释

示例中,Map/Reduce程序总共分为两块即:Map,ReduceMap负责处理输入文件的内容。

mapper方法,它以空格为分隔符将一行切分为若干tokens,之后,输出< <word>, 1> 形式的键值对。

对于示例中的第一个输入,map输出是: < Hello, 1> < World, 1> < Bye, 1> < World, 1>

第二个输入,map输出是: < Hello, 1> < Hadoop, 1> < Goodbye, 1> < Hadoop, 1>

第一个map的输出是: < Bye, 1> < Hello, 1> < World, 2>

第二个map的输出是: < Goodbye, 1> < Hadoop, 2> < Hello, 1>

reduce收到的数据是这样的:

< Bye , [1]> < GoodBye , [1]> < Hadoop , [1,1]> < Hello , [1,1]> < World , [1,1]>

Reducer中的reduce方法 仅是将每个key(本例中就是单词)出现的次数求和。 hadoop-streaming只来自各个mapper的键值对按照键排序,不会合并,因此我们需要自己将排序后的键值对合并成<键, 值列表>的形式后再发给reduce程序处理,recuder.py中的main()就是为了实现这个功能。

因此这个作业的输出就是: < Bye, 1> < Goodbye, 1> < Hadoop, 2> < Hello, 2> < World, 2>

请同学们先熟悉上面的流程,然后再进入下面的任务。

编程要求

使用MapReduce计算班级每个学生的最好成绩,输入文件路径为/user/test/input,请将计算后的结果输出到/user/test/output/目录下。

测试说明

输入文件在你每次点击评测的时候,平台会为你创建,无需你自己创建,只需要启动HDFS,编写python代码即可。

输入文件的数据格式如下: 张三 12 李四 13 张三 89 李四 92 ...

依照如上格式你应该输出:

张三 89 李四 92

答案:

mapper.py:

def mapper(line):

    ##########  begin      ############

    group = line.split('\\n')
    for people in group:
        if len(people.strip()) == 0:
            continue
        name, age = people.split(' ')

    ###########  End  ################

mapper函数输入的是一行一行的数据,对每一行数据用‘\n’进行分割得到的是<姓名 年龄>这样的字符串,再次分割得到name = 姓名,age = 年龄 ,输出。

reducer.py:

# 找出values的最大值,并按name\tmax_age的形式输出。
def reducer(k, values):
    ##### Begin #########
 
    print("%s\t%s" % (k,max(values)))
    
    #####  End  #########

 reducer函数的输入是<姓名,年龄数组>,要求最大的年龄只需要用max(values)即可,然后输出。 

第二关:文件内容合并去重

任务描述

本关任务:使用Map/Reduce编程实现文件合并和去重操作。

相关知识

通过上一小节的学习我们了解了MapReduce大致的使用方式,本关我们来了解一下Mapper类,Reducer类和调用方法。

编程要求

接下来我们通过一个练习来巩固学习到的MapReduce知识吧。

对于两个输入文件,即文件file1和文件file2,请编写MapReduce程序,对两个文件进行合并,并剔除其中重复的内容,得到一个新的输出文件file3。 为了完成文件合并去重的任务,你编写的程序要能将含有重复内容的不同文件合并到一个没有重复的整合文件,规则如下:

  • 第一列按学号排列;
  • 学号相同,按x,y,z排列;
  • 输入文件路径为:/user/tmp/input/
  • 输出路径为:/user/tmp/output/

注意:输入文件后台已经帮你创建好了,不需要你再重复创建。

测试说明

程序会对你编写的代码进行测试: 输入已经指定了测试文本数据:需要你的程序输出合并去重后的结果。 下面是输入文件和输出文件的一个样例供参考。

输入文件file1的样例如下: 20150101 x 20150102 y 20150103 x 20150104 y 20150105 z 20150106 x

输入文件file2的样例如下: 20150101 y 20150102 y 20150103 x 20150104 z 20150105 y

根据输入文件file1file2合并得到的输出文件file3的样例如下:

20150101 x 20150101 y 20150102 y 20150103 x 20150104 y 20150104 z 20150105 y 20150105 z 20150106 x

mapper.py:

def mapper(line):
    ########## Begin  ###############
    items = line.split('\\n')
    
    for item in items:
        key,value = item.split()
        print("%s\t%s" % (key,value))
 
    ###########  End    #############

mapper函数中,因为数据是一行一行的处理,没有办法实现去重,所以去重的任务只能由reducer函数来完成。

reducer.py

def reducer(k, values):
    ############  Begin   ################
   
    value = sorted(list(set(values)))
    for v in value:
        print("%s\t%s" % (k,v))
   
    ############   End    ################

mapper函数中,因为数据是一行一行的处理,没有办法实现去重,所以去重的任务只能由reducer函数来完成。

第三关:信息挖掘 - 挖掘父子关系:

任务描述

本关任务:对给定的表格进行信息挖掘。

编程要求

你编写的程序要能挖掘父子辈关系,给出祖孙辈关系的表格。规则如下:

  • 孙子在前,祖父在后;
  • 输入文件路径:/user/reduce/input
  • 输出文件路径:/user/reduce/output

测试说明

程序会对你编写的代码进行测试: 下面给出一个child-parent的表格,要求挖掘其中的父子辈关系,给出祖孙辈关系的表格。

输入文件内容如下: child parent Steven Lucy Steven Jack Jone Lucy Jone Jack Lucy Mary Lucy Frank Jack Alice Jack Jesse David Alice David Jesse Philip David Philip Alma Mark David Mark Alma

输出文件内容如下:


  
  1. grand_child grand_parent
  2. Mark Jesse
  3. Mark Alice
  4. Philip Jesse
  5. Philip Alice
  6. Jone Jesse
  7. Jone Alice
  8. Steven Jesse
  9. Steven Alice
  10. Steven Frank
  11. Steven Mary
  12. Jone Frank
  13. Jone Mary

mapper.py

def mapper(line):
    ###############  Begin   ############
    
    items = line.split("\\n")
    for item in items:
        child,parent = item.split()
        print("%s\t%s" % (child,"p-"+parent))
        print("%s\t%s" % (parent,"c-"+child))
    
    ###############   End    #############

      由于mapper只能一行一行的处理数据,所以按照<子女,父母><父母,子女>的形式进行两次输出,并且在第二个值前加上‘c-’或‘p-’以区分这个人到底是父母还是子女。

reducer.py

def reducer(k, values):
    ##############    Begin    ################
    
    grandc = []
    grandp = []
    for value in values:
        if value[:2] == 'c-':
            grandc.append(value[2:])
        elif value[:2] == 'p-':
            grandp.append(value[2:])
    
    for c in grandc:
        for p in grandp:
            print("%s\t%s" % (c,p))
       
    ##############   End      #################

  reducer函数进行的工作就是将得到的数据进行整合,根据数据前面的‘c-’,‘p-’来判断这个人是父母还是子女,父母放入grandp列表中,子女放入grandc列表中(放入列表时不要忘记去掉前面的‘c-’和‘p-’),最后将其对应的关系输出。

这就是本次作业所有的内容了,希望大家能从中获得一些什么。蟹蟹

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python版MapReduce基础实战 的相关文章

  • curl命令

    在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具 xff0c 可以说是一款很强大的http命令行工具 它支持文件的上传和下载 xff0c 是综合传输工具 xff0c 但按传统 xff0c 习惯称url为下载工具 htt
  • Docker基本命令

    一 安装docker 1 docker运行时需要到管理员用户权限 现在我们是普通用户 xff0c 终端内输入命令 su root切换为root用户 使用apt get update 更新软件源中的所有软件列表 2 使用apt install
  • Nmap常用命令

    nmap hostname ip 或者多个 ip 或者子网 192 168 123 iL ip txt 扫描 ip txt 的所有 ip A 包含了 sV xff0c O xff0c 探测操作系统信息和路由跟踪 一般不用 xff0c 是激烈
  • Jmeter性能测试(6)--元件的作用域与执行顺序

    jmeter xff08 六 xff09 元件的作用域与执行顺序 jmeter是一个开源的性能测试工具 xff0c 它可以通过鼠标拖拽来随意改变元件之间的顺序以及元件的父子关系 xff0c 那么随着它们的顺序和所在的域不同 xff0c 它们
  • sql,逻辑漏洞,xss,反序列化思维导图

  • Arduino MAX30102脉搏心率传感器使用教程

    最近闲来无事 xff0c 得到了一块MAX30102 xff0c 手头刚好有多余的Arduino控制板 xff0c 就跑了个官方的案例 xff0c 发现测出来的脉搏和心率还是挺准的 xff0c 三星手机用过这个系列的芯片 xff0c 但是有
  • 两种方法用IDEA创建一个Servlet程序 新手教程详解

    1 Servlet 是什么 xff1f Java Servlet 是运行在 Web 服务器或应用服务器上的程序 xff0c 它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层 2
  • reduce()累计器理解与使用实例

    关于reduce reduce 语法 xff1a arr reduce callback accumulator currentValue index array initialValue arr reduce accumulator cu
  • {}与Object.create(null)

    var one 61 创建的对象带有 proto 下面有一些方法与属性 xff0c 这便是js的原型链继承 xff0c 继承了object的方法和属性 xff1b 故在遍历对象时 xff0c 会遍历原型链上的属性 xff0c 带来性能上的损
  • uni-app 全局变量机制

    getApp globalData 全局变量机制 在App vue中 export default globalData text 39 text 39 在App vue中调用 this globalData text在onLaunch生命
  • vue3动态注册路由

    在vue cil2中 xff0c 我们可以通过webpack中require context这个api实现工程自动化 xff0c 而在vue cil3里vite替代了webpack xff0c 节省了webpack冗长的打包时间的同时我们也
  • try{}catch(res){}、throw(exception)、new Error()

    1 try catch res try 中的代码出现错误异常时 xff0c 系统会将异常信息封装到error对象中 xff0c 传递给catch res xff0c 包含res message res name等 EvalError eva
  • new Map()

    1 new Map let data 61 new Map data set key value 添加一个新建元素到映射 Map 1 key 61 gt value data get key 返回映射中的指定元素 data has key
  • Proxy代理

    Proxy用于修改某些操作的默认行为 xff0c 等同于在语言层面做出修改 xff0c 所以属于一种 元编程 语法 xff1a let proxy 61 new Proxy target handler target 所要拦截的目标对象ha
  • Jmeter性能测试(7)--定时器

    jmeter xff08 七 xff09 定时器 jmeter提供了很多元件 xff0c 帮助我们更好的完成各种场景的性能测试 xff0c 其中 xff0c 定时器 xff08 timer xff09 是很重要的一个元件 xff0c 最新的
  • oninput完美限制输入正整数

    oninput完美限制输入非0正整数 注意vue中需要 64 input进行绑定 方法一 64 input 61 34 if this value length 61 61 1 this value 61 this value replac
  • 行内存放数据属性data-id

    data 61 39 data 39 为行内存放数据的属性 xff0c 可通过事件源中的currentTarget dataset获取data 存放的值 另外css可通过 data 放置的标签名 data 61 39 data 39 设置
  • js常用封装方法

    span class token comment 生成随机数 64 length 指定长度 return 随机数 span span class token keyword export span function span class t
  • 计数器组件

    涉及事件 64 longpress 长按时触发 xff0c 64 touchend 手指从屏幕上离开时触发 1 计数器为文本标签的子组件 lt template gt lt view class 61 34 counter box 34 g
  • rich-text 富文本

    rich text 富文本 普通的text文件不能显示格式 xff0c 富文本格式rtf文件可以显示出很多格式信息 xff0c 比如可以在一个文本包含不同颜色 不同字号的文本 官方 lt rich text nodes 61 34 cont

随机推荐

  • uni-app实现全局组件注册

    uni app 全局注册组件三种方式 1 传统vue组件需要创建 引用 组成三个步骤 2 在page json中对应page设置 34 globalStyle 34 34 autoscan 34 true 和pages同级 3 HBuild
  • Vue--混入(Mixin)

    Vue 混入 Mixin 当不同组件有相同功能时 xff0c 不必重复定义属性和方法 xff0c 可使用vue中的混入 Mixin 来分发 Vue 组件中的可复用功能 一个 mixin 对象可以包含任意组件选项 xff0c 即data me
  • uni-app--tabs切换swiper

    父组件 span class token operator lt span template span class token operator gt span span class token operator lt span view
  • 关于移动端 html5诸多事件

    1 点击事件 64 click与 64 tap的区别 xff1a 64 click 在web手机端上点击 xff0c 有300ms延迟再被触发 64 tap具有事件穿透特点 而 64 click没有 事件冒泡 xff1a 当父元素有点击事件
  • vuex状态管理

    vue 1 下载vuex依赖 2 创建store目录store js xff0c 然后在js中引入 span class token keyword import span span class token module Vue span
  • Jmeter性能测试(8)--断言

    jmeter xff08 8 xff09 断言 jmeter中有个元件叫做断言 xff08 Assertion xff09 xff0c 它的作用和loadrunner中的检查点类似 xff1b 用于检查测试中得到的响应数据等是否符合预期 x
  • Class类

    class类的基本写法 es6引入了class类的概念 xff0c 可通过class关键字来定义类每个类都会有一个构造函数 xff0c 即constructor 方法 xff0c 用于创建和初始化class对象要注意 xff0c 如果一个类
  • install与directive

    install Vue option Vue js提供install方法 xff0c 可用于开发新插件以及全局注册组件等 span class token keyword export span span class token keywo
  • STC15W4K56S4学习笔记——LCD12864滚动显示

    STC15W4K56S4学习笔记 LCD12864滚动显示 最近在准备学校的单片机校赛 xff0c 重新回顾了一遍51单片机 xff0c 上手了STC15W4K56S4试验箱 xff0c 写一些笔记来记录一下 xff0c 水平有限 xff0
  • STM32用XCOM调试助手打印不出数据

    STM32用XCOM调试助手打印不出数据 被困扰了一段时间的串口终于解决了 xff0c 用STM332F103ZET6写串口 xff0c 但是不懂为什么打开串口调试助手就是打印不出数据 首先检查了代码有没有错 xff0c 因为是按照网上的代
  • OpenCV-python学习笔记(十二)——图像轮廓

    十二 图像轮廓 图像轮廓是指将边缘连接起来形成的一个整体 xff0c 用于后续的计算 因为边缘检测得到的边缘是不连续的 查找图像内的轮廓信息 xff1a cv2 findContours 绘制轮廓 xff1a cv2 drawContour
  • k210——maix bit串口通信

    k210 串口通信 k210 一共有3个 uart xff0c 每个 uart 可以进行自由的引脚映射 一 API函数介绍 1 1 register pin function force 61 True K210 可以通过映射来改变引脚功能
  • k210——Maixhub 云端模型训练

    k210 Maixhub 云端模型训练 一 前言 k210的模型训练可以在Maixhub 上进行 xff0c 只需要准备好需要训练的数据集 xff0c 不需要搭建训练环境和代码 xff0c 上传训练数据即可快速训练出模型 Maixhub 有
  • 自动控制原理MATLAB常用函数总结

    自动控制原理MATLAB常用函数总结 一 控制系统的数学模型 1 传递函数数学模型 G xff08 s xff09 61
  • MCS-51汇编软件实验

    MCS 51汇编软件实验 实验一 内存块移动 将指定源地址和长度的存储块移到指定目标地址为起始地址的单元中去 移动3000H起始的256个字节到4000H起始的256个字节 代码示例 xff1a ORG 0000H MOV DPTR 300
  • Jmeter性能测试(9)--逻辑控制器

    jmeter中逻辑控制器 xff08 Logic Controllers xff09 的作用域只对其子节点的sampler有效 xff0c 作用是控制采样器的执行顺序 jmeter提供了17种逻辑控制器 xff0c 它们各个功能都不尽相同
  • MapReduce的工作流程:map和reduce分别做了哪些工作,以及shuffle机制实现了什么

    一 map和reduce分别做了哪些工作 Map 待处理数据分片放入缓冲区 xff0c 分区 排序 合并 归并 xff0c 写入本地磁盘 将处理杂乱无章的数据 xff0c 找出规律 xff0c 归纳处理 1 读取hdfs上的文件 xff0c
  • Prometheus监控部署

    文章目录 一 通用监控系统基础知识以及Prometheus的概述1 监控系统的发展史 xff1a 2 什么是Prometheus 二 工作原理及适用性1 prometheus获取数据的方式 三 xff0c 实验环境1 关闭防火墙和核心防护P
  • Docker之 神操作!居然能修改已运行的 Docker 容器端口映射

    文章目录 一 容器未启动 xff1f 二 容器已启动 xff1f 2 1 但是想修改或者添加端口时 xff0c 先停止掉正在运行的容器 2 2 查看容器完整的 96 hash of the container 96 数值 xff1a 2 3
  • python版MapReduce基础实战

    第一关 xff1a 成绩统计 任务描述 本关任务 xff1a 使用Map Reduce计算班级中年龄最大的学生 相关知识 为了完成本关任务 xff0c 你需要掌握 xff1a 1 什么是MapReduce xff0c 2 如何使用MapRe