Mapreduce实例(二):求平均值

大家好,我是风云,欢迎大家关注我的博客 或者 微信公众号【笑看风云路】,在未来的日子里我们一起来学习大数据相关的技术,一起努力奋斗,遇见更好的自己!

实现思路

求平均数是MapReduce比较常见的算法,求平均数的算法也比较简单,一种思路是Map端读取数据,在数据输入到Reduce之前先经过shuffle,将map函数输出的key值相同的所有的value值形成一个集合value-list,然后将输入到Reduce端,Reduce端汇总并且统计记录数,然后作商即可。具体原理如下图所示:

img

编写代码

Mapper代码

public static class Map extends Mapper<Object , Text , Text , IntWritable>{  
  private static Text newKey=new Text();  
  //实现map函数  
  public void map(Object key,Text value,Context context) throws IOException, InterruptedException{  
    // 将输入的纯文本文件的数据转化成String  
    String line=value.toString();  
    System.out.println(line);  
    String arr[]=line.split("\t");  
    newKey.set(arr[0]);  
    int click=Integer.parseInt(arr[1]);  
    context.write(newKey, new IntWritable(click));  
  }  
}

map端在采用Hadoop的默认输入方式之后,将输入的value值通过split()方法截取出来,我们把截取的商品点击次数字段转化为IntWritable类型并将其设置为value,把商品分类字段设置为key,然后直接输出key/value的值。

Reducer代码

public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable>{  
  //实现reduce函数  
  public void reduce(Text key,Iterable<IntWritable> values,Context context) throws IOException, InterruptedException{  
    int num=0;  
    int count=0;  
    for(IntWritable val:values){  
      num+=val.get(); //每个元素求和num  
      count++;        //统计元素的次数count  
    }  
    int avg=num/count;  //计算平均数  

    context.write(key,new IntWritable(avg));  
  }  
}  

map的输出<key,value>经过shuffle过程集成<key,values>键值对,然后将<key,values>键值对交给reduce。reduce端接收到values之后,将输入的key直接复制给输出的key,将values通过for循环把里面的每个元素求和num并统计元素的次数count,然后用num除以count 得到平均值avg,将avg设置为value,最后直接输出<key,value>就可以了。

完整代码

package mapreduce;  
import java.io.IOException;  
import org.apache.hadoop.conf.Configuration;  
import org.apache.hadoop.fs.Path;  
import org.apache.hadoop.io.IntWritable;  
import org.apache.hadoop.io.NullWritable;  
import org.apache.hadoop.io.Text;  
import org.apache.hadoop.mapreduce.Job;  
import org.apache.hadoop.mapreduce.Mapper;  
import org.apache.hadoop.mapreduce.Reducer;  
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;  
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;  
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;  
public class MyAverage{  
  public static class Map extends Mapper<Object , Text , Text , IntWritable>{  
    private static Text newKey=new Text();  
    public void map(Object key,Text value,Context context) throws IOException, InterruptedException{  
      String line=value.toString();  
      System.out.println(line);  
      String arr[]=line.split("\t");  
      newKey.set(arr[0]);  
      int click=Integer.parseInt(arr[1]);  
      context.write(newKey, new IntWritable(click));  
    }  
  }  
  public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable>{  
    public void reduce(Text key,Iterable<IntWritable> values,Context context) throws IOException, InterruptedException{  
      int num=0;  
      int count=0;  
      for(IntWritable val:values){  
        num+=val.get();  
        count++;  
      }  
      int avg=num/count;  
      context.write(key,new IntWritable(avg));  
    }  
  }  
  public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException{  
    Configuration conf=new Configuration();  
    System.out.println("start");  
    Job job =new Job(conf,"MyAverage");  
    job.setJarByClass(MyAverage.class);  
    job.setMapperClass(Map.class);  
    job.setReducerClass(Reduce.class);  
    job.setOutputKeyClass(Text.class);  
    job.setOutputValueClass(IntWritable.class);  
    job.setInputFormatClass(TextInputFormat.class);  
    job.setOutputFormatClass(TextOutputFormat.class);  
    Path in=new Path("hdfs://localhost:9000/mymapreduce4/in/goods_click");  
    Path out=new Path("hdfs://localhost:9000/mymapreduce4/out");  
    FileInputFormat.addInputPath(job,in);  
    FileOutputFormat.setOutputPath(job,out);  
    System.exit(job.waitForCompletion(true) ? 0 : 1);  

  }  
}

-------------- end ----------------

微信公众号:扫描下方二维码或 搜索 笑看风云路 关注
笑看风云路

  • 2
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑看风云路

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值