Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 使用数据框';s模式_Scala_Apache Spark_Apache Spark Sql - Fatal编程技术网

Scala 使用数据框';s模式

Scala 使用数据框';s模式,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,我有一个从JSON对象创建的数据帧。我可以查询这个数据框并将其写入拼花地板 由于我推断模式,所以我不一定知道数据帧中有什么 有没有一种方法可以使用自己的模式输出列名或映射数据帧 // The results of SQL queries are DataFrames and support all the normal RDD operations. // The columns of a row in the result can be accessed by field index: df

我有一个从JSON对象创建的数据帧。我可以查询这个数据框并将其写入拼花地板

由于我推断模式,所以我不一定知道数据帧中有什么

有没有一种方法可以使用自己的模式输出列名或映射数据帧

// The results of SQL queries are DataFrames and support all the normal  RDD operations.
// The columns of a row in the result can be accessed by field index:
df.map(t => "Name: " + t(0)).collect().foreach(println)

// or by field name:
df.map(t => "Name: " + t.getAs[String]("name")).collect().foreach(println)

// row.getValuesMap[T] retrieves multiple columns at once into a Map[String, T]
df.map(_.getValuesMap[Any](List("name", "age"))).collect().foreach(println)
// Map("name" -> "Justin", "age" -> 19)
我想做点像

df.map (_.getValuesMap[Any](ListAll())).collect().foreach(println)
// Map ("name" -> "Justin", "age" -> 19, "color" -> "red")

在不知道列的实际数量或名称的情况下。

好吧,您可以这样做,但结果是毫无用处的:

val df = Seq(("Justin", 19, "red")).toDF("name", "age", "color")

def getValues(row: Row, names: Seq[String]) = names.map(
  name => name -> row.getAs[Any](name)
).toMap

val names = df.columns
df.rdd.map(getValues(_, names)).first

// scala.collection.immutable.Map[String,Any] = 
//   Map(name -> Justin, age -> 19, color -> red)

要获得真正有用的东西,需要在SQL类型和Scala类型之间进行适当的映射。这在简单的情况下并不困难,但在一般情况下是困难的。例如,有一个内置类型可以用来表示任意的
结构。这可以使用一点元编程来完成,但可以说这并不值得大惊小怪。

您可以使用隐式编码器并在数据帧本身上执行映射:

implicit class DataFrameEnhancer(df: DataFrame) extends Serializable {
    implicit val encoder = RowEncoder(df.schema)

    implicit def mapNameAndAge(): DataFrame = {
       df.map(row => (row.getAs[String]("name") -> row.getAs[Int]("age")))
    }
}
并在数据帧上调用它,如下所示:

val df = Seq(("Justin", 19, "red")).toDF("name", "age", "color")
df.mapNameAndAge().first
这样,您就不必将数据帧转换为RDD(在某些情况下,您不想从磁盘加载整个DF,只加载一些列,但RDD转换强制您这样做。此外,您使用编码器而不是Kryo(或其他Java Serde),速度要快得多

希望有帮助:-)