繁体   English   中英

从Spark中嵌套的其他DF / RDD(Nested Json)创建DF / RDD

[英]Create DF/RDD from nested other DF/RDD (Nested Json) in Spark

我是Spark&Scala方面的新手,如果有人可以向我解释一下,那就太好了。 让我们跟随以下JSON

    {
    "id": 1,
    "persons": [{
        "name": "n1",
        "lastname": "l1",
        "hobbies": [{
            "name": "h1",
            "activity": "a1"
        },
        {
            "name": "h2",
            "activity": "a2"
        }]
    },
    {
        "name": "n2",
        "lastname": "l2",
        "hobbies": [{
            "name": "h3",
            "activity": "a3"
        },
        {
            "name": "h4",
            "activity": "a4"
        }]
    }]
    }

我正在将此Json通过sc.parralelize(file.json)加载到RDD,并通过sqlContext.sql.load.json(file.json)加载到DF。 到目前为止,到目前为止,这已经为我提到的Json提供了RDD和DF(带有模式),但是我想从现有的RDD / DF创建另一个RDD / DF,其中包含所有不同的“爱好”记录。 我该如何实现……? 我从操作中获得的唯一东西是多个WrappedArrays for Hobbies,但我无法深入研究,也无法将它们分配给DF / RDD。

到目前为止的SqlContext代码

    val jsonData = sqlContext.read.json("path/file.json")
    jsonData.registerTempTable("jsonData") //I receive schema for whole file
    val hobbies = sqlContext.sql("SELECT persons.hobbies FROM jasonData") //subschema for hobbies
    hobbies.show()

那让我

    +--------------------+
    |             hobbies|
    +--------------------+
    |[WrappedArray([a1...|
    +--------------------+

我期望的更像是:

    +--------------------+-----------------+
    |             name   |        activity |
    +--------------------+-----------------|
    |                  h1|              a1 |
    +--------------------+-----------------+
    |                  h2|              a2 |
    +--------------------+-----------------+
    |                  h3|              a3 |
    +--------------------+-----------------+
    |                  h4|              a4 |
    +--------------------+-----------------+

我将您的示例完全按照您的方式加载到数据框hobbies并进行了处理。 您可以运行以下内容:

val distinctHobbies = hobbies.rdd.flatMap {row => row.getSeq[List[Row]](0).flatten}.map(row => (row.getString(0), row.getString(1))).distinct
val dhDF = distinctHobbies.toDF("activity", "name")

这实际上使您的兴趣爱好结构变平,将其转换为元组,并对返回的元组运行不同的内容。 然后,我们将其转回到正确列别名下的数据框。 由于我们是通过底层的RDD进行此操作的,因此,可能还有一种更有效的方法来仅使用DataFrame API来执行此操作。

无论如何,当我运行您的示例时,我看到:

scala> val distinctHobbies = hobbies.rdd.flatMap {row => row.getSeq[List[Row]](0).flatten}.map(row => (row.getString(0), row.getString(1))).distinct
distinctHobbies: org.apache.spark.rdd.RDD[(String, String)] = MapPartitionsRDD[121] at distinct at <console>:24

scala> val dhDF = distinctHobbies.toDF("activity", "name")
dhDF: org.apache.spark.sql.DataFrame = [activity: string, name: string]

scala> dhDF.show
...
+--------+----+
|activity|name|
+--------+----+
|      a2|  h2|
|      a1|  h1|
|      a3|  h3|
|      a4|  h4|
+--------+----+

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM