【问题标题】:Scala - Convert Dataframe into json file and make key from column name and column value both for different different columnsScala - 将 Dataframe 转换为 json 文件,并为不同的不同列从列名和列值生成键
【发布时间】:2020-06-13 22:14:19
【问题描述】:

我想将 Spark DataFrame 转换为 Json 文件。下面是输入和输出格式。 任何帮助表示赞赏。

Input :

+-------------------------+
|Name|Age|City |Data      |
+-------------------------+
|Ram |30 |Delhi|[A -> ABC]|
|-------------------------|
|Shan|25 |Delhi|[X -> XYZ]|  
|-------------------------|
|Riya|12 |U.P. |[M -> MNO]|
+-------------------------+

Output : 

{"Name":"Ram","Age":"30","City":"Delhi","Delhi":{"A":"ABC"}}
{"Name":"Shan","Age":"25","City":"Delhi","Delhi":{"X":"XYZ"}}
{"Name":"Riya","Age":"12","City":"U.P.","U.P.":{"M":"MNO"}}

【问题讨论】:

    标签: json scala dataframe dictionary nested


    【解决方案1】:

    您可以在 DataFrame 上调用write.json。

    val df: DataFrame = ....
    df.write.json("/jsonFilPath")
    

    这是一个使用数据集的示例

    scala> case class Data(key: String, value: String)
    
    scala> case class Person(name: String, age: Long, city: String, data: Data)
    
    scala> val peopleDS = Seq(Person("Ram", 30, "Delhi", Data("A", "ABC")), Person("Shan", 25, "Delhi", Data("X", "XYZ")), Person("Riya", 12, "U.P", Data("M", "MNO"))).toDS()
    
    scala> peopleDS.show()
    +----+---+-----+--------+
    |name|age| city|    data|
    +----+---+-----+--------+
    | Ram| 30|Delhi|[A, ABC]|
    |Shan| 25|Delhi|[X, XYZ]|
    |Riya| 12|  U.P|[M, MNO]|
    +----+---+-----+--------+
    
    scala> peopleDS.write.json("pathToData/people")
    

    然后你会在给定的文件夹中找到写入的 json 文件。

    > cd pathToData/people
    > ls -l
    
    part-00000-6bd00826-5a8e-4ab9-bfb0-65d722394108-c000.json
    
    > cat part-00000-6bd00826-5a8e-4ab9-bfb0-65d722394108-c000.json
    
    {"name":"Ram","age":30,"city":"Delhi","data":{"key":"A","value":"ABC"}}
    {"name":"Shan","age":25,"city":"Delhi","data":{"key":"X","value":"XYZ"}}
    {"name":"Riya","age":12,"city":"U.P","data":{"key":"M","value":"MNO"}}
    
    
    

    【讨论】:

    • 嗨@Lamanus,toJson 在这里无济于事,因为最后一列我不希望列名作为键。我想将列值作为关键。嗨 Sithroo,你能帮忙解决一下吗,我不知道如何使用 write.json 从 Dataframe 获取这种 json
    • @AnamikaSingh,我已经更详细地扩展了我的答案。希望对你有所帮助。
    • 嗨@Sithroo,感谢您的回答,但我的输出略有不同,对于最后一列,我想从行值而不是列名“数据”中创建键。 {"Name":"Ram","Age":"30","City":"Delhi","Delhi":{"A":"ABC"}} {"Name":"Shan","Age ":"25","City":"Delhi","Delhi":{"X":"XYZ"}} {"Name":"Riya","Age":"12","City":" UP","UP":{"M":"MNO"}}
    • @AnamikaSingh 输出格式为:{"name":"Ram","age":30,"city":"Delhi","data":{"Delhi":{"A":"ABC"}}} {"name":"Shan","age":25,"city":"Delhi","data":{"Delhi":{"X":"XYZ"}}} {"name":"Riya","age":12,"city":"U.P","data":{"U.P":{"M":"MNO"}}}?
    • 嗨@Sithroo,请您帮忙解决以下问题:(?stackoverflow.com/questions/60772949/…
    【解决方案2】:

    Scala:从你的数据出发,

    val df = Seq(("Ram",30,"Delhi",Map("A" -> "ABC")), ("Shan",25,"Delhi",Map("X" -> "XYZ")), ("Riya",12,"U.P.",Map("M" -> "MNO"))).toDF("Name", "Age", "City", "Data")
    df.show
    
    // +----+---+-----+----------+
    // |Name|Age| City|      Data|
    // +----+---+-----+----------+
    // | Ram| 30|Delhi|[A -> ABC]|
    // |Shan| 25|Delhi|[X -> XYZ]|
    // |Riya| 12| U.P.|[M -> MNO]|
    // +----+---+-----+----------+
    

    要将密钥更改为City 而不是Data,

    val df2 = df.groupBy("Name", "Age", "City").pivot("City").agg(first("Data"))
    df2.show
    
    // +----+---+-----+----------+----------+
    // |Name|Age| City|     Delhi|      U.P.|
    // +----+---+-----+----------+----------+
    // |Riya| 12| U.P.|      null|[M -> MNO]|
    // |Shan| 25|Delhi|[X -> XYZ]|      null|
    // | Ram| 30|Delhi|[A -> ABC]|      null|
    // +----+---+-----+----------+----------+
    

    然后使用toJson 并收集它。

    val jsonArray = df.toJSON.collect
    jsonArray.foreach(println)
    

    它会打印出如下结果:

    {"Name":"Riya","Age":12,"City":"U.P.","U.P.":{"M":"MNO"}}
    {"Name":"Shan","Age":25,"City":"Delhi","Delhi":{"X":"XYZ"}}
    {"Name":"Ram","Age":30,"City":"Delhi","Delhi":{"A":"ABC"}}
    

    【讨论】:

    • 嗨@Lamanus,但对于最后一个列键,应该是行值而不是列名,请查看下面的最后一个嵌套 json 的输出。 {"Name":"Ram","Age":"30","City":"Delhi","Delhi":{"A":"ABC"}} {"Name":"Shan","Age ":"25","City":"Delhi","Delhi":{"X":"XYZ"}} {"Name":"Riya","Age":"12","City":" UP","UP":{"M":"MNO"}}
    • 哦,我错过了。有点奇怪的键设置,但你可以通过枢轴来完成。
    • 非常感谢,这个答案给出了准确的答案并解决了我的问题。我现在得到了预期的答案:)
    • 嗨@Lamanus,你能帮忙stackoverflow.com/questions/60772949/…吗,我提供了有问题的运行代码。
    猜你喜欢
    • 2021-07-27
    • 1970-01-01
    • 2020-07-11
    • 2019-08-06
    • 2018-01-15
    • 1970-01-01
    • 1970-01-01
    • 2020-12-31
    • 1970-01-01
    相关资源
    最近更新 更多