Hadoop 读取csv MapReduce中的空单元格时的ArrayIndexOutofBounds

Hadoop 读取csv MapReduce中的空单元格时的ArrayIndexOutofBounds,hadoop,mapreduce,hdfs,Hadoop,Mapreduce,Hdfs,我正在尝试为以下数据运行MapReduce程序 这是我的映射程序代码: @Override protected void map(Object key, Text value, Mapper.Context context) throws IOException, ArrayIndexOutOfBoundsException,InterruptedException { String tokens[]=value.toString().split(","); if(tokens

我正在尝试为以下数据运行MapReduce程序

这是我的映射程序代码:

@Override
protected void map(Object key, Text value, Mapper.Context context) throws IOException, ArrayIndexOutOfBoundsException,InterruptedException {
    String tokens[]=value.toString().split(",");
    if(tokens[6]!=null){
        context.write(new Text(tokens[6]), new IntWritable(1));
    }

}
由于我的一些单元格数据是空的,当我试图读取列Carrier_delay时,我得到以下错误。请告知

17/04/13 20:45:29 INFO mapreduce.Job: Task Id : attempt_1491849620104_0017_m_000000_0, Status : FAILED
Error: java.lang.ArrayIndexOutOfBoundsException: 6
    at Test.TestMapper.map(TestMapper.java:22)
    at Test.TestMapper.map(TestMapper.java:17)
    at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:145)
    at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:764)
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:340)
    at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:168)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:422)


所有列都是图像中显示的列吗?如果是这种情况,请记住java数组的索引为0,列的范围为0到5,因此标记[6]超出了范围。或者,根据您的必要逻辑,您还可以在您的if中添加验证:

if(tokens.length>n&&tokens[n]!=null){ write(新文本(标记[n]),新intwriteable(1)); }


载波延迟是第二个字段,因此您需要使用令牌[1]进行访问,因为数组索引从0开始。您还可以在访问特定索引之前进行长度检查。令牌[6]出现错误,因为您总共有6列。如果您访问的是最后一个字段,那么它将是令牌[5],即长度减1。

问题在于:
如果(令牌[6]!=null){

问题是您希望获取令牌[6]的值,然后检查它是否为空。但是,有些行只包含六列(第七列为空),因此在这些情况下,
令牌
,是一个六元素数组。这意味着它包含从
令牌[0]
令牌[5]的值
。当您尝试访问
令牌[6]
时,您超出了数组的大小,因此您得到了ArrayIndexOutOfBoundsException

做你想做的事的正确方法是:

IntWritable one = new IntWritable(1); //this saves some time ;)
Text keyOutput = new Text(); //the same goes here

@Override
protected void map(Object key, Text value, Mapper.Context context) throws IOException, ArrayIndexOutOfBoundsException,InterruptedException {
    String tokens[]=value.toString().split(",");
    if(tokens.length == 7){
        keyOutput.set(tokens[6]);
        context.write(keyOutput, one);
    }

}

更多提示:根据您的部分代码判断,我猜您需要计算特定值的运营商延迟出现的次数。在这种情况下,您还可以使用组合器来加快处理速度,就像WordCount程序所做的那样。您还可以将运营商延迟解析为可写的整数,以节省时间和空间。

年,航空公司ID,ORIGIN_AIRPORT_ID,ORIGIN,DEST_AIRPORT_ID,ARR_DELAY CARRIER_DELAY。这是订单,我在添加和条件后再次收到相同的错误。17/04/13 21:30:19信息mapreduce。作业:任务ID:trunt_1491849620104_0019_m_0000000,状态:失败错误:java.lang.ArrayIndexOutOfBoundsException:6 at Test.Test.Mapper.Mapper(TestMapper.java:22)位于Test.TestMapper.map(TestMapper.java:17)您正在使用逗号作为拆分器,但可能有空值的行没有正确的逗号数,因此Tokens数组的值较少,请粘贴文件的屏幕截图,但在文本编辑器上或使用cat在命令行中打开它,以便我们可以检查mmm,奇怪,输入文件似乎很好,我将进行一些调试,如果需要,请注释当前文件语句,而将映射器输出作为行本身的键,并作为tokens.lenght的值,类似于:context.write(value,new IntWritable(tokens.length));我可以向您发送csv文件吗?年份,航空公司ID,始发地机场ID,始发地,目的地机场ID,AR‌​延迟载波‌​Y.这是我的列顺序。我在中间截取了数据。你可以只搜索你试图访问的文件。看看你是否为所有7个字段都设置了分隔符。如果部分字段为空,分隔符逗号应该仍然存在,然后你可以进行长度检查。如果你可以从.hdfs fi粘贴前10条记录,效果会更好le.thiyagarajans MacBook Pro:Dataset nirmal$cat ONTIME.csv,head-10,column-s-t“年”、“航空公司ID”、“始发地机场ID”、“始发地机场ID”、“目的地机场ID”、“到达延迟”、“承运人延迟”、“天气延迟”、“飞机延迟”、“安全延迟”、“晚点飞机延迟”,20161980511298,“DFW”,11433,-6.00,11433,7.00,,,,,,,,20161980511298,“DFW”,11433,-5.00,,,,,,,,,20161980511298,“DFW”,11433113.00,0.00,0.00,47.00,0.00,66.00,是否可以粘贴驱动程序代码段。您使用默认输入格式还是keyvalueinputformat
IntWritable one = new IntWritable(1); //this saves some time ;)
Text keyOutput = new Text(); //the same goes here

@Override
protected void map(Object key, Text value, Mapper.Context context) throws IOException, ArrayIndexOutOfBoundsException,InterruptedException {
    String tokens[]=value.toString().split(",");
    if(tokens.length == 7){
        keyOutput.set(tokens[6]);
        context.write(keyOutput, one);
    }

}