使用Hadoop MapReduce从CSV文件中收集特定数据

时间:2015-04-17 20:29:48

标签: java csv hadoop mapreduce

我需要MapReduce程序的一些帮助。我有一个包含15个列的CSV文件。我试图根据第三列的值(年份)从两个列(市场和金额资助)中提取数据。

截至目前,我的程序为每个条目输出两列(市场和金额资助)的数据。我希望它输出的是指定年份每个市场的资金总额或指定年份范围内每个市场的资金总额。

我将在下面发布我的映射器代码以及示例数据条目。任何帮助将不胜感激!

public class FundingMapper extends MapReduceBase implements Mapper<LongWritable, Text, Text, Text> {
private Text market = new Text();
private Text amount = new Text();

public void map(LongWritable key, Text value, OutputCollector<Text,Text> output, Reporter reporter) throws IOException {
    String line = value.toString();
    CSVReader R = new CSVReader(new StringReader(line));

    String[] ParsedLine = R.readNext();
    R.close();

    amount.set(ParsedLine[15]);
    market.set(ParsedLine[3]);

    output.collect(market, amount);
}
}

/organization/hashoff, #HASHOFF, |Digital Media|Internet|Social Media|, Digital Media, USA, CO, Denver, Denver, /funding-round/669d6203c0374e6cf0e8d10f75ba0b8a, debt_financing, 12/8/14, 2014-12, 2014-Q4, 2014, 455,000

对于上述条目,我的程序将分别使用正确的标题输出Digital Media和455,000 for Market和Amount Funded。我希望程序根据年份或指定的年份范围输出结果。

这里也是我的工作代码:

public static void main(String[] args) throws IOException {
    JobConf conf = new JobConf(FundingJob.class);

    conf.setJobName("Funding Data");

    conf.setOutputKeyClass(Text.class);
    conf.setOutputValueClass(Text.class);
    conf.setMapOutputKeyClass(Text.class);
    conf.setMapOutputValueClass(Text.class);

    conf.setMapperClass(FundingMapper.class);
    conf.setNumReduceTasks(0);

    FileInputFormat.addInputPath(conf, new Path(args[0]));
    FileOutputFormat.setOutputPath(conf, new Path(args[1]));
    JobClient.runJob(conf);
}
}

1 个答案:

答案 0 :(得分:3)

您输出的是市场的关键值和价值的数量,我认为您希望转向关键的年度市场连接。通过使用这样的密钥,您将能够生成(键,值)对的列表,如下例所示:

2014-DigitalMedia,455000
2014-OtherMarket,34500
2014-DigitalMedia,100000
2015-DigitalMedia,120000
2015-DigitalMedia,67000
2015-OtherMarket,15000
2015-OtherMarket,10000
...

然后,reducer类可以获得每个元组并聚合每个键的数量,结果:

2014-DigitalMedia,555000
2014-OtherMarket,34500
2015-DigitalMedia,187000
2015-OtherMarket,25000

reducer的代码可能是这样的:

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

public void reduce(Text key, Iterator<IntWritable> values, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
    int sum = 0;

    while (values.hasNext()) {
        sum += values.next().get();
    }

    output.collect(key, new IntWritable(sum));
}

在主程序中,您必须添加:

conf.setCombinerClass(Reduce.class);
conf.setReducerClass(Reduce.class);