统计某年每个月的汽车销售数量的比例实现比例计算
时间: 2023-12-25 07:04:17 浏览: 32
统计某年每个月的汽车销售数量的比例,可以使用Hadoop MapReduce编写一个MapReduce作业来完成。具体步骤如下:
1. Mapper阶段:将数据读取并转换为键值对,其中键是年份和月份,值是销售数量。Mapper代码如下:
```
public class SalesMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
private Text yearMonth = new Text();
private IntWritable sales = new IntWritable();
public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
// 解析每行记录,获取年份、月份和销售数量
String[] fields = value.toString().split(",");
String dateStr = fields[0];
int qty = Integer.parseInt(fields[1]);
// 将日期转换为年份和月份
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = dateFormat.parse(dateStr);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1;
// 设置键值对
yearMonth.set(year + "-" + month);
sales.set(qty);
// 输出键值对
context.write(yearMonth, sales);
}
}
```
2. Reducer阶段:对Mapper阶段输出的键值对进行聚合和计算,得到每个月的销售总数量。Reducer代码如下:
```
public class SalesReducer extends Reducer<Text, IntWritable, Text, DoubleWritable> {
private DoubleWritable ratio = new DoubleWritable();
public void reduce(Text key, Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
int sum = 0;
for (IntWritable value : values) {
sum += value.get();
}
// 计算比例
ratio.set((double)sum / totalSales);
// 输出结果
context.write(key, ratio);
}
}
```
在Reducer阶段,我们需要计算每个月的销售总数量,并根据年份和月份计算比例。为了计算比例,我们需要在Mapper阶段先统计总销售量。可以在Driver类中定义一个变量来保存总销售量,并在Mapper阶段累加每个月的销售数量。具体代码如下:
```
public class SalesDriver {
public static void main(String[] args) throws Exception {
// 创建Job对象
Job job = Job.getInstance();
// 设置Job的各种属性
job.setJarByClass(SalesDriver.class);
job.setMapperClass(SalesMapper.class);
job.setReducerClass(SalesReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
// 设置输入输出路径
FileInputFormat.setInputPaths(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
// 计算总销售量
long totalSales = 0;
FileSystem fs = FileSystem.get(job.getConfiguration());
RemoteIterator<LocatedFileStatus> fileStatusIter = fs.listFiles(new Path(args[0]), true);
while (fileStatusIter.hasNext()) {
LocatedFileStatus fileStatus = fileStatusIter.next();
if (!fileStatus.isDirectory()) {
BufferedReader reader = new BufferedReader(new InputStreamReader(fs.open(fileStatus.getPath())));
String line = null;
while ((line = reader.readLine()) != null) {
String[] fields = line.split(",");
int qty = Integer.parseInt(fields[1]);
totalSales += qty;
}
reader.close();
}
}
// 设置总销售量到Reducer类中
job.getConfiguration().setLong("totalSales", totalSales);
// 提交Job并等待完成
job.waitForCompletion(true);
}
}
```
在Reducer阶段,我们需要从Configuration对象中获取总销售量,并计算每个月的销售比例。具体代码如下:
```
public class SalesReducer extends Reducer<Text, IntWritable, Text, DoubleWritable> {
private DoubleWritable ratio = new DoubleWritable();
private long totalSales;
public void setup(Context context) {
totalSales = context.getConfiguration().getLong("totalSales", 0);
}
public void reduce(Text key, Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
int sum = 0;
for (IntWritable value : values) {
sum += value.get();
}
// 计算比例
ratio.set((double)sum / totalSales);
// 输出结果
context.write(key, ratio);
}
}
```
这样,就可以完成统计某年每个月的汽车销售数量的比例的实现。