此map-reduce用于计算" Hadoop:定义指南"
中的示例的每年和每月的平均温度输出应为
年[TAB]月[TAB] average_temperature
由于密钥(年份+月份)已经合并,是否可以使用substring()和context.write(年[TAB]月[TAB] average_temperature)?或者处理这个问题的常用方法是什么?如下(不正确)?
context.write(key.toString()。substring(0,4),key.toString()。substring(4,6),average);
protected void reduce(Text key, Iterable<TemperatureAveragingPair> values, Context context) throws IOException, InterruptedException {
int temp = 0;
int count = 0;
for (TemperatureAveragingPair pair : values) {
temp += pair.getTemp().get();
count += pair.getCount().get();
}
average.set(temp / count);
context.write(key, average);
}
答案 0 :(得分:0)
经过课程,有些事情对我来说很奇怪。
首先,您的Mapper输出<Text, IntWritable>
不符合Reducer / Combiner输入<Text, TemperatureAveragingPair>
。这些应该是同步的,否则作业将失败而不会在编译中出现任何问题。
你说&#39;由于密钥(年+月)已合并&#39; ,我假设NcdcRecordParser
中的以下陈述取得年份+月份(肯定在yyMM格式):
year = record.substring(15, 19);
但上述陈述与之相矛盾:
context.write(key.toString().substring(0, 4),key.toString().substring(4, 6), average);
表示yyyyMM格式。在上一种情况下,您似乎无法将月份添加到年份字符串中。
无论如何,让我们明白这一点。您是对的,您可以使用substring
方法分隔年份和月份,如图所示。但为此你必须从Mapper
发出相同格式的密钥。接下来,您不需要使用TemperatureAveragingPair
作为Reducer
的值,一个简单的IntWritable
将执行此操作并删除异常。现在它看起来像:
private Text tabKey = new Text();
private StringBuilder builder = new StringBuilder();
public void reduce(Text key, Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
int temp = 0;
int count = 0;
for (IntWritable value : values) {
temp += value.get();
count ++;
}
average.set(temp / count);
builder.setLength(0);
builder.append(key.toString());
builder.insert(4, "\t");
tabKey.setText(builder.toString());
context.write(tabKey, average);
}