我遇到问题,要确定每个文件的单词出现次数的细分。 例如,我有四个文本文件(t1,t2,t3,t4)。单词w1在文件t2中是两次,在t4中是一次,总发生次数为3。 我想在输出文件中写入相同的信息。 我在每个文件中获得了总字数,但无法得到我想要的结果。
这是我的地图类。
import java.io.IOException;
import java.util.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;
//line added
import org.apache.hadoop.mapreduce.lib.input.*;
public class Map extends Mapper<LongWritable, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
private String pattern= "^[a-z][a-z0-9]*$";
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
StringTokenizer tokenizer = new StringTokenizer(line);
//line added
InputSplit inputSplit = context.getInputSplit();
String fileName = ((FileSplit) inputSplit).getPath().getName();
while (tokenizer.hasMoreTokens()) {
word.set(tokenizer.nextToken());
String stringWord = word.toString().toLowerCase();
if ((stringWord).matches(pattern)){
//context.write(new Text(stringWord), one);
context.write(new Text(stringWord), one);
context.write(new Text(fileName), one);
//System.out.println(fileName);
}
}
}
}
答案 0 :(得分:0)
您可以将word
key
和filename
写为value
来实现。现在在reducer中为每个文件初始化单独的计数器并更新它们。一旦为特定键迭代了所有值,就将每个文件的计数器写入上下文。
在这里你知道你只有四个文件,所以你可以硬编码四个变量。请记住,您需要为在reducer中处理的每个新键重置变量。
如果文件数量更多,则可以使用Map。在地图中,filename
将为key
并继续更新value
。
答案 1 :(得分:0)
在mapper的输出中,我们可以将文本文件名设置为键,将文件中的每一行设置为值。此缩减器为您提供该单词的文件名及其相应的计数。
public class Reduce extends Reducer<Text, Text, Text, Text> {
HashMap<String, Integer>input = new HashMap<String, Integer>();
public void reduce(Text key, Iterable<Text> values , Context context)
throws IOException, InterruptedException {
int sum = 0;
for(Text val: values){
String word = val.toString(); -- processing each row
String[] wordarray = word.split(' '); -- assuming the delimiter is a space
for(int i=0 ; i<wordarray.length; i++)
{
if(input.get(wordarray[i]) == null){
input.put(wordarray[i],1);}
else{
int value =input.get(wordarray[i]) +1 ;
input.put(wordarray[i],value);
}
}
context.write(new Text(key), new Text(input.toString()));
}