展平Spark数据框的列值并将其放入变量中

时间:2018-11-25 01:25:38

标签: scala apache-spark dataframe

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在展平它们之后获取唯一值。

如何获得所需的输出?

2 个答案:

答案 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 ,因为您希望在该列上使用不同的元素。