2016-08-17 28 views
0

我是SPARK的新手,所以试图做一个小程序并且遇到下面的错误。 有人可以帮忙吗?SPARK的管道分隔文件中的数据帧

仅供参考 - 当样本文件中的列中没有空数据时,程序似乎工作,但问题似乎是由于第二行中的空值引起的。

数据:TEMP_EMP.dat

1232|JOHN|30|IT 
1532|DAVE|50| 
1542|JEN|25|QA 
内容

SCALA代码来解析该数据转换成dataframes

import org.apache.spark.sql.Row; 
import org.apache.spark.sql.types.{StructType, StructField, StringType}; 
val employee = sc.textFile("file:///TEMP_EMP.dat") 
val textFileTemp = sc.textFile("file:///TEMP_EMP.dat"); 
val schemaString = "ID|NAME|AGE|DEPT"; 
val schema = StructType(schemaString.split('|').map(fieldName=>StructField(fieldName,StringType,true))); 
val rowRDD = employee.map(_.split('|')).map(e => Row(e(0),e(1),e(2), e(3))); 
val employeeDF = sqlContext.createDataFrame(rowRDD, schema); 
employeeDF.registerTempTable("employee"); 
val allrecords = sqlContext.sql("SELECT * FROM employee"); 
allrecords.show(); 

错误日志:

WARN 2016年8月17日13:36:21006 org.apache.spark.scheduler.TaskSetManager:失去任务0.0在阶段6.0:java.lang.ArrayIndexOutOfBoundsException:3

回答

0

这是我们应该如何把它分解:

val schema = StructType(
       schemaString 
        .split("|",-1) 
        .map(fieldName => StructField(fieldName,StringType,true)) 
      ); 

val rowRDD = employee 
       .map(_.split("|", -1)) 
       .map(e => Row(e(0),e(1),e(2),e(3))); 
+0

这是如何解决范围下标的初始问题的? – swdev

0

这条线:

val rowRDD = employee.map(_.split('|')).map(e => Row(e(0),e(1),e(2), e(3))); 

您假定employee.map(_.split('|'))的结果至少有四个元素,但第二行只有3个,因此索引超出界限异常。

举例说明:

scala> val oneRow = "1532|DAVE|50|".split('|') 
oneRow: Array[String] = Array(1532, DAVE, 50) 

scala> oneRow(3) 
java.lang.ArrayIndexOutOfBoundsException: 3 
+0

确定这是有道理的。但是这是一个非常好的方案,因为这些文本文件可以将任何列数据设置为空,我们应该能够在代码中处理它以将值设置为空。 有关如何在此代码中处理此任何想法? – baburam1985

+0

请参阅:http://stackoverflow.com/questions/16231254/how-to-get-an-option-from-index-in-collection-in-scala,这也让你使用'Option'而不是'null ',这通常更好(防止空指针异常)。 – spiffman