Spark version 1.60
,Scala version 2.10.5
。
我有一个spark-sql
数据帧df
,
+-------------------------------------------------+
|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
而不是找到this,因此,尝试使用,将其放入变量中,
val allValues = df.withColumn(df("attributes"), explode("attributes"))
但是我遇到一个错误:
错误:类型不匹配;found:org.apache.spark.sql.column
必填:字符串
我在考虑是否可以使用explode
获得输出,我可以使用distinct
在展平它们之后获取唯一值。
如何获得所需的输出?
答案 0 :(得分:2)
我强烈建议您使用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
如果“属性”列不是数组,而是逗号分隔的字符串,则使用下面的字符串,它会为您提供相同的结果
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)
答案 1 :(得分:1)
问题是withColumn
在其第一个参数(这是添加的列的名称)中需要一个 String ,但是您正在传递它df.withColumn(df("attributes")
的列。
您只需传递"attributes"
作为字符串。
此外,您需要将列传递给explode
函数,但是您要将 String -传递给使其成为一列,您可以使用df("columName")
或Scala速记 $ 语法$"columnName"
。
希望此示例可以为您提供帮助。
import org.apache.spark.sql.functions._
val allValues = df.select(explode($"attributes").as("attributes")).distinct
请注意,这只保留了attributes
列,因为您希望在该列上使用不同的元素。