[英]How to load data into Teradata table using FASTLOAD through Spark dataframe
[英]How to load data into Product case class using Dataframe in Spark
我有一個文本文件,並且具有如下數據:
productId|price|saleEvent|rivalName|fetchTS
123|78.73|Special|VistaCart.com|2017-05-11 15:39:30
123|45.52|Regular|ShopYourWay.com|2017-05-11 16:09:43
123|89.52|Sale|MarketPlace.com|2017-05-11 16:07:29
678|1348.73|Regular|VistaCart.com|2017-05-11 15:58:06
678|1348.73|Special|ShopYourWay.com|2017-05-11 15:44:22
678|1232.29|Daily|MarketPlace.com|2017-05-11 15:53:03
777|908.57|Daily|VistaCart.com|2017-05-11 15:39:01
我必須找到各個網站上產品的最低價格,例如,我的輸出應該是這樣的:
productId|price|saleEvent|rivalName|fetchTS
123|45.52|Regular|ShopYourWay.com|2017-05-11 16:09:43
678|1232.29|Daily|MarketPlace.com|2017-05-11 15:53:03
777|908.57|Daily|VistaCart.com|2017-05-11 15:39:01
我正在這樣嘗試:
case class Product(productId:String, price:Double, saleEvent:String, rivalName:String, fetchTS:String)
val cDF = spark.read.text("/home/prabhat/Documents/Spark/sampledata/competitor_data.txt")
val (header,values) = cDF.collect.splitAt(1)
values.foreach(x => Product(x(0).toString, x(1).toString.toDouble,
x(2).toString, x(3).toString, x(4).toString))
運行最后一行時獲取異常:
java.lang.ArrayIndexOutOfBoundsException: 1
at org.apache.spark.sql.catalyst.expressions.GenericRow
.get(rows.scala:174)
at org.apache.spark.sql.Row$class.apply(Row.scala:163)
at
org.apache.spark.sql.catalyst.expressions.GenericRow
.apply(rows.scala:166
)
at $anonfun$1.apply(<console>:28)
at $anonfun$1.apply(<console>:28)
at scala.collection.IndexedSeqOptimized$class.foreach
(IndexedSeqOptimized.scala:33)
at
scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:186)
... 49 elided
以值定價:
scala> values
res2: **Array[org.apache.spark.sql.Row]** = `
Array([123|78.73|Special|VistaCart.com|2017-05-11 15:39:30 ],
[123|45.52|Regular|ShopYourWay.com|2017-05-11 16:09:43 ],
[123|89.52|Sale|MarketPlace.com|2017-05-11 16:07:29 ],
[678|1348.73|Regular|VistaCart.com|2017-05-11 15:58:06 ],
[678|1348.73|Special|ShopYourWay.com|2017-05-11 15:44:22 ],
[678|1232.29|Daily|MarketPlace.com|2017-05-11 15:53:03 ],
[777|908.57|Daily|VistaCart.com|2017-05-11 15:39:01 ]`
scala>
我能夠理解我需要split("|")
。
scala> val xy = values.foreach(x => x.toString.split("|").toSeq)
xy: Unit = ()
因此,在將其划分給我的Unit
類(即void)之后,因此無法將值加載到Product
case類中。 如何將此數據框加載到Product
案例類? 我現在不想使用數據集,盡管數據集類型安全。
我正在使用Spark 2.3和Scala 2.11。
問題是由於使用正則表達式進行split
,這意味着您需要使用"\\\\|"
而不是單個"|"
。 另外,需要更改foreach
來map
以實際給出一個返回值,即:
val xy = values.map(x => x.toString.split("\\|"))
但是,更好的方法是使用|
將數據讀取為csv文件|
分隔符。 這樣,您就無需以特殊方式對待標頭,並且不需要通過推斷列類型就可以進行任何轉換(這里我將fetchTS
更改為時間戳):
case class Product(productId: String, price: Double, saleEvent: String, rivalName: String, fetchTS: Timestamp)
val df = spark.read
.option("header", "true")
.option("inferSchema", "true")
.option("sep", "|")
.csv("/home/prabhat/Documents/Spark/sampledata/competitor_data.txt")
.as[Product]
最后一行將轉換數據框以使用Product
案例類。 如果要將其用作RDD,只需在末尾添加.rdd
。
完成此操作后,使用groupBy
和agg
獲得最終結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.