spark scala中的数据框映射?

时间:2017-11-14 10:24:01

标签: scala apache-spark apache-spark-sql spark-dataframe scala-collections

我有一个如下所示的数据集

INo,Sc,Desc,Quan,IDate,UPice,CID,Country
1,2,"H,H",6,12-1-2010 8:26,2.55,c1,United Kingdom
2,3,"WE,RN",6,12-1-2010 8:26,3.39,c2,United Kingdom
3,3,CREAM ,8,12-1-2010 8:26,2.75,c3,United Kingdom
4,4,KLE,6,12-1-2010 8:26,3.39,c4,United Kingdom
5,5,"DI,AMR,ROR, ",2,1-7-2011 13:55,11.02,c5,United Kingdom
6,6,SU"asasa,1,12-9-2010 16:26,11.02,c6,United Kingdom

我通过执行以下代码创建了数据框:

case class Rating(CID: String, SC: String, rating: Double)
def parseRating(str: String): Rating = {
val fields = str.split(",")
Rating(fields(6), fields(1), 1.0D)
}
val ratings = spark.read.textFile("C:/Users/test/Desktop/test123.txt").map(parseRating).toDF().dropDuplicates("CID", "SC")
ratings.collect().map(t => println(t))
ratings.show()

我得到的输出如下

+---------------+---+------+
|            CID| SC|rating|
+---------------+---+------+
|12-9-2010 16:26|  6|   1.0|
|             c3|  3|   1.0|
|            CID| Sc|   1.0|
|             c4|  4|   1.0|
|           3.39|  3|   1.0|
|              2|  5|   1.0|
|           2.55|  2|   1.0|
+---------------+---+------+

我来到这里是因为field=str.split(",")。输入数据是 6,6,“SET,CO,SU”,1,12-9-2010 16:26,11.02,c6,英国

但是我的预期输出是

+---------------+---+------+
|            CID| SC|rating|
+---------------+---+------+
|             c6|  6|   1.0|
|             c3|  3|   1.0|
|             c2|  3|   1.0|
|             c4|  4|   1.0|
|             c5|  5|   1.0|
|             c1|  2|   1.0|
+---------------+---+------+ 

请帮我解决这个问题。

2 个答案:

答案 0 :(得分:1)

如果您使用的是Spark 2,则可以执行以下操作:

val data = spark.read.option("header", true).csv("test123.txt")
data.select("CID", "Sc").withColumn("rating", lit(1.0)).show
+---+---+------+
|CID| Sc|rating|
+---+---+------+
| c1|  2|   1.0|
| c2|  3|   1.0|
| c3|  3|   1.0|
| c4|  4|   1.0|
| c5|  5|   1.0|
| c6|  6|   1.0|
+---+---+------+

答案 1 :(得分:0)

您无法使用","直接拆分每条记录。由于某些列值已经得到了","作为值不作为分隔符。例如" H,H"在第一条记录中,

你需要一个正则表达式进行拆分,如下所示,

def parseRating(str: String): Rating = {
val fields = str.split("\\,(?=([^\"]*\"[^\"]*\")*[^\"]*$)")
Rating(fields(6), fields(1), 1.0D)
}

此外,您的第一行是标题。在加载数据文件时将标题添加为true,或在加载数据文件后过滤第一行。