首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在mapreduce中求平均值

如何在mapreduce中求平均值
EN

Stack Overflow用户
提问于 2014-04-30 01:39:03
回答 2查看 2.3K关注 0票数 2

问题:我们想要取存储在文本文件中的平均工资。假设文件包含名字、姓氏和薪水。假设我们想要为美国所有的公司,所有规模的公司做这件事。新的一天开始一个新的文件,即所有在4月29日输入的工资都在标题为April29.txt的文件中,所有在4月30日输入的工资都在标题为April30.text的文件中,依此类推。你可以想象每天的行号都是不同的。

目标:使用mapreduce计算每个文件的平均工资。

现在我到处看,总体建议做平均值是这样的: map一次读取一行,并输出" key ",value,因为只有一个key- "key“所有输出到一个reducer,在那里我们使用for循环来计算平均值。

这种方法很好,只是文件越大,计算时间就越长。有没有办法改善这种情况?我没有找到解决这种情况的例子,但如果你知道一些例子,请分享一个链接。提前谢谢。

EN

回答 2

Stack Overflow用户

发布于 2014-04-30 02:47:54

这绝对可以更有效地完成。

现在,我们知道Mapper有一个可以覆盖的map方法。但是,它也有一个cleanup。查看映射器的源代码,您会看到以下内容:

代码语言:javascript
运行
复制
public void run(Context context) throws IOException, InterruptedException {
  setup(context);
  while (context.nextKeyValue()) {
    map(context.getCurrentKey(), context.getCurrentValue(), context);
  }
  cleanup(context);
}

因此,我们可以使用这种清理方法来优化我们的平均代码。

首先,您需要一个自定义的可写对象来存储两个内容:countsum。让我们称它为AverageWritable。然后,我们将在映射器中执行类似以下操作:

代码语言:javascript
运行
复制
AverageWritable avg = new AverageWritable();
public void map(LongWritable key, Text value, Context ctx) {
    long salary = [ ... code to get salary... ]
    avg.addCount(1);
    avg.addSum(salary);
}

public void cleanup(Context ctx) {
    ctx.write(CONSTANT_KEY, avg);
}

reducer和combiner代码应该很容易从这里弄清楚。

票数 3
EN

Stack Overflow用户

发布于 2015-01-28 19:02:13

我很好奇,因为我们可以使用hadoop提供的计数器来做这件事。假设我们构建了两个计数器,例如

公共枚举计数器{ CountCounters }

公共枚举计数器{ SumCounters }

从我们的映射器的map方法中,我们可以访问计数器并递增它。

context.getCounter(CountCounters.Counter).increment(1);context.getCounter(SumCounters.Counter).increment();

最后我们会

job.getCounters().findCounter(CountCounters.Counter).getValue();job.getCounters().findCounter(SumCounters.Counter).getValue();

找出平均值

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23371598

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档