【问题标题】:How to read a value with nested fields in Spark? [duplicate]如何在 Spark 中读取具有嵌套字段的值? [复制]
【发布时间】:2018-12-23 21:41:40
【问题描述】:

我拥有的数据集充满了嵌套字段。例如data.take(1) 的输出有 9 列,其中第 4 列 (c4) 有 3 个子字段,而 c4 的第 1 列有 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 中的任何答案。

【问题讨论】:

  • 那么,您基本上想知道您的数据集/数据框的架构?
  • @addmeaning 是的,没错。事实上,我将架构作为 AVSC 文件,但我不确定如何将架构映射到这些记录,因为数据不容易采用 JSON 格式。

标签: database scala apache-spark pyspark


【解决方案1】:

如果您已经使用 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]|
+---------+-----------+

现在,如果您想获得嵌套列,例如,您只需要嵌套类 NestedLevel 中的 value 列,您可以只写 df.select("nestedLevel.value").show() 这将返回您

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

【讨论】:

  • 谢谢,这正是我想要的。该架构与我拥有的 AVSC 文件非常吻合。但是,我不确定如何浏览它。例如,row(n) 给出第 n 列,但 row(n)(m) 抛出一个错误,说 Any 不带参数。如何操作子字段?
  • 我会更新我的答案。
  • 哈哈刚来这里,看到了泰米尔语中持有'Onnu,Rendu'的值。很高兴看到:-) @addmeaning
  • 我有一个类似的问题here,但它是关于遍历模式的。你能看一下吗?顺便说一句,泰米尔语数字很好玩。
猜你喜欢
  • 2015-07-12
  • 1970-01-01
  • 2018-07-17
  • 2021-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-26
相关资源
最近更新 更多