如何在Spark中读取带有嵌套字段的值?

时间:2018-07-16 10:55:43

标签: database scala apache-spark pyspark

我拥有的数据集到处都是嵌套字段。例如,data.take(1)的输出给出9列,其中第四列(c4)具有3个子字段,而c4的第一列具有3个子字段,依此类推。

格式看起来像这样

[A,B,C,[[d1,d2,d3],D2,D3],E,[F1,[f1,[f21,f22,f23],f3,f4],F3,F4],G,H,I]

我想要一个数组数据结构的数组(然后可以将其展开为单个数组)。

只是使数据看起来更清晰:

A
B
C
D
  -D1
    -d1
    -d2
    -d3
  -D2
  -D3
E
F
  -F1
  -F2
    -f1
    -f2
      -f21
      -f22
      -f23
    -f3
    -f4
  -F3
  -F4
G
H
I

当然,我可以编写一个解析程序,该程序将递归搜索给定记录的子字段并生成此树结构(作为数组的数组)。但是,我希望Spark中会有一个更简单,更高效的预构建例程,该例程可以直接处理此问题。

在Spark-Scala或PySpark中的任何答案将不胜感激。

1 个答案:

答案 0 :(得分:2)

如果您已经使用spark将数据帧/数据集加载到内存中,那么有两种方法可以为您提供帮助。尝试df.printSchema()df.schema,其中df是引用您的数据集的变量。第一个将在屏幕上显示包含数据类型的架构,第二个将返回StructType对象,您的代码可以遍历该对象。

更新

所以现在您要方便地选择嵌套字段。

假设您有以下代码:

import org.apache.spark.sql.SparkSession

object Question51360175 extends App{
    val session = SparkSession.builder()
      .appName("spark-app").master("local[*]").getOrCreate()

    import session.implicits._

    case class TopLevel(someField: String, nestedLevel: NestedLevel)
    case class NestedLevel(key: Int, value: String)



    val df = Seq(
      TopLevel("first", NestedLevel(1, "Onnu")),
      TopLevel("second", NestedLevel(2, "Rendu"))
    ).toDF

    df.printSchema()

  df.show()
}

这将为您提供这种输出

root
 |-- someField: string (nullable = true)
 |-- nestedLevel: struct (nullable = true)
 |    |-- key: integer (nullable = false)
 |    |-- value: string (nullable = true)

+---------+-----------+
|someField|nestedLevel|
+---------+-----------+
|    first|  [1, Onnu]|
|   second| [2, Rendu]|
+---------+-----------+

现在,如果您想获取嵌套列,例如,您只希望嵌套类value中的NestedLevel列,您只需编写df.select("nestedLevel.value").show()即可返回

+-----+
|value|
+-----+
| Onnu|
|Rendu|
+-----+