2016-08-17 45 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