2017-05-22 8 views
0

私は以下の形式のテキストファイルの文字列を持っている:どのようにカンマで文字列を分割する(、)が、二重引用符(「」)内のカンマを無視し

"1","1st",1,"Allen, Miss Elisabeth Walton",29.0000,"Southampton","St Louis, MO","B-5","24160 L221","2","female" 

を私は(カンマで文字列を分割したいです、 )を無視しますが、二重引用符( "")の中のコンマ(、)は無視します。私はSparkとScalaとcaseクラスを使ってデータフレームを作成しています。 私は以下のコードを試してみましたが、私はエラーだ:

​​

ケースクラスのコードは以下の通りです:

case class tit (Num: Int, Class: String, Survival_Code: Int, Name: String, Age: Double, Province: String, Address: String, Coach_No: String, Coach_ID: String, Floor_No:Int, Gender:String) 

エラー:

17/05/21 14:52:39 ERROR Executor: Exception in task 0.0 in stage 1.0 (TID 1) 
java.lang.NumberFormatException: For input string: "" 
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) 
    at java.lang.Integer.parseInt(Integer.java:592) 
    at java.lang.Integer.parseInt(Integer.java:615) 
    at scala.collection.immutable.StringLike$class.toInt(StringLike.scala:272) 
    at scala.collection.immutable.StringOps.toInt(StringOps.scala:29) 
    at $line27.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$anonfun$2.apply(<console>:40) 
    at $line27.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$anonfun$2.apply(<console>:31) 
    at scala.collection.Iterator$$anon$11.next(Iterator.scala:409) 
    at scala.collection.Iterator$$anon$11.next(Iterator.scala:409) 
    at scala.collection.Iterator$$anon$11.next(Iterator.scala:409) 
    at org.apache.spark.sql.execution.SparkPlan$$anonfun$4.apply(SparkPlan.scala:247) 
    at org.apache.spark.sql.execution.SparkPlan$$anonfun$4.apply(SparkPlan.scala:240) 
    at org.apache.spark.rdd.RDD$$anonfun$mapPartitionsInternal$1$$anonfun$apply$24.apply(RDD.scala:784) 
    at org.apache.spark.rdd.RDD$$anonfun$mapPartitionsInternal$1$$anonfun$apply$24.apply(RDD.scala:784) 
    at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:38) 
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:319) 
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:283) 
    at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:70) 
    at org.apache.spark.scheduler.Task.run(Task.scala:85) 
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:274) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:748) 

答えて

0

あなたはスパークのビルトインを使用する必要がありますがcsv reader

2

NumberFormatExceptionは、データ内の空き数によるもので、あなたがこれを解決するには

val tit_rdd = td.map(td=>td.split(",(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)")) 
    .map(td=>tit(Try(td(0).replaceAll("\"","").toInt) getOrElse 0 , 
    td(1).replaceAll("\"",""), 
    Try(td(2).toInt) getOrElse 0, 
    td(3).replaceAll("\"",""), 
    Try(td(4).toDouble) getOrElse 0.0, 
    td(5).replaceAll("\"",""), 
    td(6).replaceAll("\"",""), 
    td(7).replaceAll("\"",""), 
    td(8).replaceAll("\"",""), 
    Try(td(9).replaceAll("\"","").toInt) getOrElse 0, 
    td(10).replaceAll("\"",""))) 
以下のように TrygetOrElseを使用することです .toInt

を使用してIntegerに変換しようとしています

問題を解決する必要があります。

テキストファイルを変換する別の方法dataFrameへのeは、これがデフォルトに_c0ようheader namesを生成しますdatabricks csv reader

sqlContext.read.format("com.databricks.spark.csv").load("path to the text file") 

を使用することです_c1
何が

sqlContext.read.format("com.databricks.spark.csv").option("header", true).load("path to the text file") 
として、上記の行で optionをテキストファイルに header line入れてやると定義することができます

あなた自身でもっと多くのオプションで遊ぶことができます

0

あなたはCSVファイルをD ataFrame以下のようなスキーマとしてあなたのケースクラスを使用して:

val spark = org.apache.spark.sql.SparkSession.builder. 
    master("local"). 
    appName("Spark CSV"). 
    getOrCreate 

import org.apache.spark.sql.Encoders 

case class tit (Num: Int, Class: String, Survival_Code: Int, Name: String, Age: Double, Province: String, 
    Address: String, Coach_No: String, Coach_ID: String, Floor_No:Int, Gender:String) 

val schema = Encoders.product[tit].schema 

val df = spark.read.schema(schema).csv("/path/to/csv") 

df.show 
+---+-----+-------------+--------------------+----+-----------+------------+--------+----------+--------+------+ 
|Num|Class|Survival_Code|    Name| Age| Province|  Address|Coach_No| Coach_ID|Floor_No|Gender| 
+---+-----+-------------+--------------------+----+-----------+------------+--------+----------+--------+------+ 
| 1| 1st|   1|Allen, Miss Elisa...|29.0|Southampton|St Louis, MO|  B-5|24160 L221|  2|female| 
+---+-----+-------------+--------------------+----+-----------+------------+--------+----------+--------+------+ 
0

あなたは、それは二重引用符内のすべてのカンマを扱うcsvデータをロードするためにスパーク-CSVを使用することができます。ここで

は、私はこのことができます願っていますが

import org.apache.spark.sql.Encoders 

    val spark = 
    SparkSession.builder().master("local").appName("test").getOrCreate() 

    import spark.implicits._ 

    val titschema = Encoders.product[tit].schema 

    val dfList = spark.read.schema(schema = titschema).csv("data.csv").as[tit] 

    dfList.show() 

    case class tit(Num: Int, 
       Class: String, 
       Survival_Code: Int, 
       Name: String, 
       Age: Double, 
       Province: String, 
       Address: String, 
       Coach_No: String, 
       Coach_ID: String, 
       Floor_No: Int, 
       Gender: String) 

それを使用することができる方法です!

あなたはSQLContext.createDataFrameは、あなたが最初にすべての「、 『(分割可能)を』交換してください、私はこれはあなたを助けることを願って

import org.apache.spark.sql.catalyst.ScalaReflection 
val titschema = ScalaReflection.schemaFor[tit].dataType.asInstanceOf[StructType] 
0

としてScalaのリフレクションを使用することができます をするのと同じスキーマを作成したい場合# "を入力し、"# "を入力します。

scala> st.replace("""","""", "#").replace("""",""","#").replace(""","""", "#").replace(""""""", "").split("#").map("\"" + _ + "\"") 
res1: Array[String] = Array("1", "1st", "1", "Allen, Miss Elisabeth Walton", "29.0000", "Southampton", "St Louis, MO", "B-5", "24160 L221", "2", "female") 
scala> res1.size 
res2: Int = 11 
関連する問題