输出是一个文本文件,每一行第一个数字式行标,第二个数字是输入文件中每一行除行标外数字的平均值

有时候你会遇到这样的问题:你有一个表格,给出了每个人在十二月,一月和二月的收入。

表格如下:

姓名 一月 二月 三月

楚乔     200   314   3500

宇文玥     2000  332   2300

烟熏柿子    6000  333   680

淳儿    5000  333   789

洛河     30    12    2900

现在需要知道每个人这三个月的收入平均值,那么你就需要将表格中一行代表收入的数字相加除以月数.下面请编写MR程序解决这个简单的问题。

输入只包含一个文件,它的结构如下:(数据自己做格式化)

input:

1    200    314    3500
2    2000    332    2300
3    6000    333    680
4    5000    333    789
5    30    12    2900

其中每行最前面的数字是行标

输出是一个文本文件,每一行第一个数字式行标,第二个数字是输入文件中每一行除行标外数字的平均值。

如下:

Output:

1    1338
2    1544
3    2337.67
4    2040.67
5    980.67

代码如下(由于水平有限,不保证完全正确,如果发现错误欢迎指正):

package com;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
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.output.FileOutputFormat;

public class MonthTest2 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        Configuration config = new  Configuration();
        config.set("fs.defaultFS", "hdfs://192.168.0.100:9000");
        config.set("yarn.resourcemanager.hostname", "192.168.0.100");

        FileSystem fs = FileSystem.get(config);  

        Job job = Job.getInstance(config);

        job.setJarByClass(MonthTest2.class);

        //设置所用到的map类
        job.setMapperClass(myMapper.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(Text.class);

        //设置所用到的reduce类
        job.setReducerClass(myReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);

        //设置输入输出地址
        FileInputFormat.addInputPath(job, new Path("/yuekao/month.txt"));

        Path path = new Path("/output1/");

        //判断目录文件是否存在,存在的话,删除
        if(fs.exists(path)){
            fs.delete(path, true);
        }
        //指定结果文件的输出地址
        FileOutputFormat.setOutputPath(job,path);

        //启动处理任务job
        boolean completion = job.waitForCompletion(true);
        if(completion){
            System.out.println("Job Success!");
        }
    }

    public static class myMapper extends Mapper<LongWritable,Text, Text, Text>{

        @Override
        protected void map(LongWritable key, Text value,Context context) throws IOException, InterruptedException {
            String values=value.toString();
            String words[]=values.split("\t");  //1    200    314    3500
            float avg=(Float.parseFloat(words[1])+Float.parseFloat(words[2])+Float.parseFloat(words[3]))/3;
            String aaa=String.format("%.2f", avg);//保留两位小数
            context.write(new Text(words[0]), new Text(aaa));
        }
    }

    public static class myReducer extends Reducer< Text, Text, Text, Text>{

        @Override
        protected void reduce(Text key, Iterable<Text> values,Context context) throws IOException, InterruptedException {
            for (Text value : values) {
                if(value.toString().endsWith("00")){
                    String[] aa = value.toString().split(".00");//1338.00--->aa[0]=1338
                    context.write(key,new Text(aa[0]));
                }else{
                    context.write(key, value);
                }
            }
        }

    }
}

注意:主要难点在于整数不要求保留两位小数且不要小数点,float类型的话要求保留两位小数

希望大家会喜欢~~

时间: 2024-11-05 13:43:36

输出是一个文本文件,每一行第一个数字式行标,第二个数字是输入文件中每一行除行标外数字的平均值的相关文章

linux下将编译错误输出到一个文本文件

command > filename 把把标准输出重定向到一个新文件中 command > > filename 把把标准输出重定向到一个文件中(追加) command 1 > fielname 把把标准输出重定向到一个文件中 command > filename 2> &1 把把标准输出和标准错误一起重定向到一个文件中 command 2 > filename 把把标准错误重定向到一个文件中 command 2 > > filename 把把

给定一个字符串,找到第一个只出现一次的字符的下标,找不到输出-1。

1. 给定一个字符串,找到第一个只出现一次的字符的下标,找不到输出-1. sample: 输入:"abcdefcba" 输出:3 解法:先遍历字符串,用一个map记录每个字符出现的次数,再次遍历字符串,找到第一个只出现一次的字符,复杂度为O(n). #include <iostream> #include <string> #include <cstring> #include <map> using namespace std; int

一个文本文件,找出前10个经常出现的词,但这次文件比较长,说是上亿行或十亿行,总之无法一次读入内存

Top K 算法详解应用场景: 搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节.        假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但如果除去重复后,不超过3百万个.一个查询串的重复度越高,说明查询它的用户越多,也就是越热门.),请你统计最热门的10个查询串,要求使用的内存不能超过1G. 必备知识:什么是哈希表?        哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进

lvds split两channel输出到一个屏显示

转:https://blog.csdn.net/changqing1990/article/details/81128552 其实之前写过LCD/LVDS的一些时序的基本概念<与LCD移植相关的概念>.但后来发现还是不够全面.关于双通道LVDS,可能会有很多人有一些陌生,它是什么原理? 有什么作用? 时序如何设定? 接下来, 就让我们带着这些问题去阅读下面的文章吧! 1. IMX LDB桥对LVDS 的支持情况:让我们先看一张imx6 TRM 中的图. IMX6 LVDS 桥提供两个LVDS通

一个“文本文件”打开并且保存多元化的程序细节分析

实验目标:1)提供一个文件夹浏览框,让用户选择需要打开的文本文件,打开并显示文件内容.      2)当用户点击"OK"按钮的时候,比较当前文件是否被修改过,如果修改过,则提示"覆盖保存"."放弃保存"或"另存为"并实现其功能. import easygui as g import os file_path = g.fileopenbox(default="e:/pathonaaa/a/") with op

读取文本文件中某一行

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <windows.h> #define MAX 256 int main(void) {     FILE *fa;     int i,count=0;     char ch[MAX],file[MAX]="1.txt";     if ((fa=f

C++输出二进制文件和文本文件

所谓二进制文件和文本文件对于字母而言没有什么不同,都是存储该字母的ASCII码值.能引起不同的是数字和一些排版用符号的格式. 数字在二进制文件中会存储该数字的值,而文本文件中则首先将该数字视为字符量,并按照ASCII码表转换为新的数字再存储: 排版符号的一个例子是换行符,二进制文件只是一个换行符,文本文件中则是换行符加上回车符: 所以简单的区分方法是文本文件对每个字符都要做ASCII转换,而二进制文件只会对字母做必要的ASCII转换,对数字则是直接存储的. 下来我们来讨论如何真正的实现二进制文件

怎样根据一个从一个文本文件中逐一读出每行的字符串(代表的是某个文件夹下的文件名)

怎样根据一个从一个文本文件中逐一读出每行的字符串(代表的是每个文件夹下的文件名) 目的是想根据此文本文件所存储大量的文件名,批量复制或者修改文件名所对应的文件. 在bash下用的命令是: cat /home/username/SafeAppsName.txt | xargs -I{} cp /mnt/apk/apks/{}   /home/username/apks/ 从SafeAppsName.txt中读每行字符串,代表对应文件的文件名. 然后从 /mnt/apk/apks 文件夹下进行拷贝到

有一个NSStirng类型,retain方式声明的name属性的setter方法内部每一行代码的作用?

- (void)setName:(NSString *)name { 判断原有对象和新对象是否是同一个对象,如果是同一个,就没有必要再重新赋值,否则会先release 再retain,就会变成野指针 if (_name != name) { 释放保有之前对象的所有权 [_name release]; 让实例变量 _name保有新的对象的所有权 _name = [name retain]; } } 有一个NSStirng类型,retain方式声明的name属性的setter方法内部每一行代码的作用