MapReduce程序的简化程序没有提供所需的输出

时间:2014-04-01 09:51:25

标签: java hadoop mapreduce

我正在尝试使用MapReduce构建算法属性值频率的第一阶段(频率计算),其中计算每列中每个属性的频率。我在我的问题中提到了所需的键值对。所以即使算法对你不熟悉也希望它不会有问题。我有一个数据集如下:

ID1,2,1,4
ID2,2,2,2
ID3,5,3,1

每行都有一个ID,后跟三个属性的值。在map阶段,我需要生成[attributeNo attributeValue]作为键,[ID]作为值。我已正确设计并执行了地图阶段。我通过直接在reduce阶段打印生成的键值对来测试我的map阶段,而不进行任何处理。我发现键值对已经正确生成,即,还原阶段从映射阶段获得正确的输入。我的地图类是:

public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, Text, Text> 
{              
    public void map(LongWritable key, Text value, OutputCollector<Text,Text> output, Reporter reporter) throws IOException
    {
       String[] rows = value.toString().split("\r?\n");          
       for(int i=0;i<rows.length;i++)
       {
           String[] cols = rows[i].toString().split(",");
           String v=cols[0];
           for(int j=1;j<cols.length;j++)
           {
               String k =j+","+cols[j];
               output.collect(new Text(k),new Text(v));
           }
       }
    }
 }

更正地图阶段生成的键值对:

2,3  ID3
3,2  ID2
1,5  ID3
1,2  ID1,ID2
2,1  ID1
3,4  ID1
2,2  ID2
3,1  ID3

现在,这些键值映射对作为输入提供给reduce。我的reduce阶段需要生成[ID,attributeNo]作为键,[attributeValue,frequency]作为值,其中frequency是与每个键对应的ID的数量。我的reduce类是:

public static class Reduce extends MapReduceBase implements Reducer<Text, Text, Text, Text>
{

        public void reduce(Text key, Iterator<Text> values, OutputCollector<Text, Text>output, Reporter reporter) throws IOException 
        {

            /** map phase check
            while (values.hasNext()) 
            {
               String s = (values.next()).toString();
               output.collect(key,new Text(s));            


            }**/

            // Frequency Calculation
            int count =0;                
            String[] attr = key.toString().split(",");      
            List<String> list = new ArrayList<String>();

           while(values.hasNext())               
            {
                list.add((values.next()).toString());
                count++;

            }

            String v=attr[1]+","+count;
           for(String s:list)
           { 
               String k=s+","+attr[0];
               output.collect(new Text(k),new Text(v));
           }

        } 

我得到了一个输出:

2,1,ID3  3,1
3,1,ID3  2,1
5,1,ID3  1,1
2,2,ID1  1,1
2,2,ID2  1,1
1,1,ID1  2,1
4,1,ID1  3,1
2,1,ID1  2,1
1,1,ID3  3,1

所需的输出是:

ID1,1  2,2
ID1,2  1,1
ID1,3  4,1
ID2,1  2,1
ID2,2  2,1
ID2,3  2,1
ID3,1  4,1
ID3,2  2,1
ID3,3  1,1

请告诉我在减少阶段我的代码或逻辑有什么问题?甚至在reduce阶段生成的密钥格式也不对。请帮我纠正输出到减少阶段。

0 个答案:

没有答案