Hadoop统计居民电力使用情况

分析居民电力使用状况
现有某地地区家庭用户,2006年12月至2010年11月的电力消耗数据(每分钟抽样统计一次),总共207万条,数据结构如下:

在这里插入图片描述
date代表日期
time代表时间
global_active_power代表家庭1分钟总体的平均有效功率(单位:kw)
global_reactive_power代表家庭1分钟总体的平均无功功率(单位:kw)
voltage 代表1分钟平均电压(单位:V)
global_instensity代表家庭1分钟总体的电流强度(单位:A)
sub_metering_1对应厨房的电量消耗,主要包括洗碗机、烤箱、微波炉(单位:瓦时)
sub_metering_2对应洗衣间的电量消耗,主要包括洗衣机、干洗机、冰箱和灯。
sub_metering_3对应电热水器和空调的电量消耗(单位:瓦时)

我们现在需要知道家庭用电在厨房,洗衣间,电热水器和空调三个方面哪个比较多,每一年的用电总量情况。

第一问:以年份为单位分别对后三行数据进行累加。

第一步:上传数据
第二步:开发程序
Map阶段
输入
key:每一行的偏移量
value:这一行的值
输出
key:每一年 Text ,2006 2007 2008
value: 厨房和 洗衣间和 空调和 总和
Reduce阶段
Map的输出就是Reduce的输入
reduce会自动分组排序
累加
写出
一次Reduce任务的执行分为三个阶段:
1、Reduce获取Map输入的预处理结果。
2 、将拥有相同键值对数据进行分组
3、 Reduce将用户定义的Reduce算法应用到每个键值对确定的列表中
每读一行数据就调用一次mapper
Job阶段
八股文形式
(1)字符串串联,reduce再切分
(2)创建一个类,这个类中有这些属性,Mapper中第四个泛型是这个类
上传一下源码:

具体操作

mapper阶段:

package elec;

import java.io.IOException;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
 
//每读一行数据就调用一次mapper
public class emapper extends Mapper<LongWritable,  Text, Text, Text>{
	@Override
	protected void map(LongWritable key, Text value, Context context)
			throws IOException, InterruptedException {
	   String line=value.toString();
	   String[] words=line.split(";");	  
			   if (words.length==11) {
				   String year=words[2];
				   String result=words[8]+"\t"+words[9]+"\t"+words[10];
				   context.write(new Text(year), new Text(result));
			
						   
				
			}
	}

}

reduce阶段:

package elec;

import java.io.IOException;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import com.sun.jndi.url.dns.dnsURLContextFactory;
public class ereducer extends Reducer<Text, Text, Text, Text> {
	@Override
	protected void reduce(Text key, Iterable<Text> value, Context context)
			throws IOException, InterruptedException {
		double count=0;
		double count1=0;
		double count2=0;
		double sum=0;
		for(Text i:value) {
			String[] d=i.toString().split("\t");
			
			if(!(d[0].equals("?"))||d[1].equals("?")||d[2].equals("?")) {
		 
			count =count + Double.parseDouble(d[0]);
			count1 =count1 + Double.parseDouble(d[1]);
			count2 =count2 + Double.parseDouble(d[2]);		
		}}
		sum=count+count1+count2;
		String res=count+"\t"+count1+"\t"+count2+"\t"+sum;
		context.write(key, new Text(res));
	}

}

Job阶段:

package elec;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class ejob {
public static void main(String[] args) throws Exception {
	
 
	//1.先加载配置文件
	Configuration conf=new Configuration();
	//2.创建一个job
	Job job=Job.getInstance(conf, "elec");
	//3.设置MR运行的驱动
	job.setJarByClass(ejob.class);
	//4.设置Mapper端以及他的输出类型
	job.setMapperClass(emapper.class);
	job.setMapOutputKeyClass(Text.class);
	job.setMapOutputValueClass(Text.class);
	//5.设置reduce端及输出类型
	job.setReducerClass(ereducer.class);
	job.setOutputKeyClass(Text.class);
	job.setOutputValueClass(Text.class);
	
	//6.设置输入输出结果文件路径
	FileInputFormat.setInputPaths(job, new Path(args[0]));
	FileOutputFormat.setOutputPath(job, new Path(args[1]));
	//7。提交作业
//	job.submit();  只提交不打印日志
	job.waitForCompletion(true);//提交并打印日志
	}
}

对上面三个类打成jar包,然后上传到虚拟机上运行。
奉上视频:

架包的导出及在hadoop上的运行

发布了8 篇原创文章 · 获赞 1 · 访问量 505

猜你喜欢

转载自blog.csdn.net/qq_41258650/article/details/103591982
今日推荐