Scala 展平spark数据帧';s列值并将其放入变量中
SparkScala 展平spark数据帧';s列值并将其放入变量中,scala,apache-spark,dataframe,Scala,Apache Spark,Dataframe,Spark1.60版,Scala2.10.5版 我有一个像这样的sparksqldataframedf +-------------------------------------------------+ |addess | attributes | +-------------------------------------------------+ |1314 44 Avenue | Tours, Mechanics, Sho
1.60版
,Scala2.10.5版
我有一个像这样的sparksql
dataframedf
+-------------------------------------------------+
|addess | attributes |
+-------------------------------------------------+
|1314 44 Avenue | Tours, Mechanics, Shopping |
|115 25th Ave | Restaurant, Mechanics, Brewery|
+-------------------------------------------------+
从这个数据框中,我希望得到如下值:
Tours, Mechanics, Shopping, Brewery
如果我这样做
df.select(df("attributes")).collect().foreach(println)
我知道
[Tours, Mechanics, Shopping]
[Restaurant, Mechanics, Brewery]
我想我可以使用flatMap
来代替find,所以,尝试使用
val allValues = df.withColumn(df("attributes"), explode("attributes"))
但我得到了一个错误:
错误:类型不匹配
找到:org.apache.spark.sql.column
必需:字符串
我在想,如果我可以使用explode
获得输出,我可以使用distinct
在展平后获得唯一值
如何获得所需的输出?问题在于,在其第一个参数(即添加的列的名称)中需要一个字符串,但您在此处传递一个列df.withColumn(df(“属性”)
您只需将
“attributes”
作为字符串传递即可
此外,您需要将列传递给explode
函数,但传递的是字符串——要使其成为一列,您可以使用df(“columnName”)
或Scala速记$语法,$“columnName”
希望这个例子能对你有所帮助
import org.apache.spark.sql.functions._
val allValues = df.select(explode($"attributes").as("attributes")).distinct
请注意,这将只保留
属性
列,因为您需要该列上的不同元素。我强烈建议您使用spark 2.x版本。在Cloudera中,当您发布“spark shell”时,它将发布1.6.x版本。但是,如果您发布“spark2 shell”,您将获得2.x shell。请与管理员联系
但如果您需要使用Spark 1.6和rdd解决方案,请尝试以下方法
import spark.implicits._
import scala.collection.mutable._
val df = Seq(("1314 44 Avenue",Array("Tours", "Mechanics", "Shopping")),
("115 25th Ave",Array("Restaurant", "Mechanics", "Brewery"))).toDF("address","attributes")
df.rdd.flatMap( x => x.getAs[mutable.WrappedArray[String]]("attributes") ).distinct().collect.foreach(println)
结果:
Brewery
Shopping
Mechanics
Restaurant
Tours
如果“attribute”列不是数组,而是逗号分隔的字符串,那么使用下面的一个,它会给出相同的结果
val df = Seq(("1314 44 Avenue","Tours,Mechanics,Shopping"),
("115 25th Ave","Restaurant,Mechanics,Brewery")).toDF("address","attributes")
df.rdd.flatMap( x => x.getAs[String]("attributes").split(",") ).distinct().collect.foreach(println)
您好@user9431057,我更新了答案,希望现在能有所帮助。我还建议您搜索scala入门教程,互联网上有很多,其中很多都是专门针对spark新手的。@user9431057您使用的spark&scala版本是什么?我使用的是spark
1.60
,scala版本2.10.5
@user9431057啊,这就解释了。问题是array\u distinct
是spark2.4.0
中添加的一个新函数。但是我注意到它无法解决您的问题,因为您需要整个列的唯一值,而不仅仅是每个数组。我将更新答案。很抱歉,仍然收到一个错误无法解决由于数据类型不匹配而分解(“属性”)。函数分解的输入应为数组或映射类型,而不是StringType
任何向下投票的人,请给出您的理由(特别是对于新手)。这给了我们改正错误的指导,并鼓励我们学习。然后,它让每个人都能看到哪里出了问题。无意冒犯,我们都会一起学习,从错误中学习。(有文档可以问一个好问题,但有时很难,需要一点推动:)