分析居民电力使用状况
现有某地地区家庭用户,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上的运行
来源:CSDN
作者:root666/
链接:https://blog.csdn.net/qq_41258650/article/details/103591982