我有一些数据集,我想计算每条记录的最小值,最大值和平均值(例如:userID_1 - minimum_1-- maximum_1 - avg)。
这是我的代码,我需要知道该怎么做才能让我为这个单键写下这些值:
public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> {
public void reduce(Text key, Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
int sum = 0;
int visitsCounter = 0;
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
float avg;
for (IntWritable val : values) {
int currentValue = val.get();
sum += currentValue;
visitsCounter++;
min = Math.min(min, currentValue);
max = Math.max(max, currentValue);
}
avg = sum / visitsCounter;
//here can be the supposed edit to let me output (user - min - max - avg )
context.write(key, new IntWritable(sum));
}
}
答案 0 :(得分:1)
在MapReduce中,数据按两个阶段的键值对进行流动,即映射阶段和减少阶段。
因此,我们需要在地图级别和降低级别设计键值对。
此处键和值数据类型是可写的。
键可以由多个值组成,值可以由多个值组成。
对于原子值的情况,我们使用IntWritable,DoubleWritable,LongWritable,FloatWritable等......
对于复杂的键和值数据案例,我们使用文字数据类型或用户定义的数据类型。
用于处理此方案的简单解决方案是使用文本数据类型,即将所有这些列连接到String对象中,并将此String对象序列化为Text对象。但由于大数据集上的大量字符串连接,这是效率低下。
使用自定义/用户定义的数据类型来处理这种情况。 使用 Hadoop API 中的Writable或WritableComparable 界面编写自定义数据类型。
public static class Reduce extends Reducer<Text, IntWritable, Text, Text> {
Text emitValue = new Text()
public void reduce(Text key, Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
int sum = 0;
int visitsCounter = 0;
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
float avg;
for (IntWritable val : values) {
int currentValue = val.get();
sum += currentValue;
visitsCounter++;
min = Math.min(min, currentValue);
max = Math.max(max, currentValue);
}
avg = sum / visitsCounter;
String myValue = min + "\t" + max + "\t" + avg;
emitValue.set(myValue);
//here can be the supposed edit to let me output (user - min - max - avg )
context.write(key, emitValue);
}
}