วิธีแปลง spark dataframe เป็นรายการโครงสร้างในสกาล่า

ฉันมี spark dataframe ประกอบด้วย 12 แถวและคอลัมน์ต่าง ๆ ในกรณีนี้ 22 แถว

ฉันต้องการแปลงเป็น dataframe ในรูปแบบ:

root
 |-- data: array (nullable = false)
 |    |-- element: struct (containsNull = false)
 |    |    |-- ast: double (nullable = true)
 |    |    |-- blk: double (nullable = true)
 |    |    |-- dreb: double (nullable = true)
 |    |    |-- fg3_pct: double (nullable = true)
 |    |    |-- fg3a: double (nullable = true)
 |    |    |-- fg3m: double (nullable = true)
 |    |    |-- fg_pct: double (nullable = true)
 |    |    |-- fga: double (nullable = true)
 |    |    |-- fgm: double (nullable = true)
 |    |    |-- ft_pct: double (nullable = true)
 |    |    |-- fta: double (nullable = true)
 |    |    |-- ftm: double (nullable = true)
 |    |    |-- games_played: long (nullable = true)
 |    |    |-- seconds: double (nullable = true)
 |    |    |-- oreb: double (nullable = true)
 |    |    |-- pf: double (nullable = true)
 |    |    |-- player_id: long (nullable = true)
 |    |    |-- pts: double (nullable = true)
 |    |    |-- reb: double (nullable = true)
 |    |    |-- season: long (nullable = true)
 |    |    |-- stl: double (nullable = true)
 |    |    |-- turnover: double (nullable = true)

โดยที่แต่ละองค์ประกอบของฟิลด์ dataframe data สอดคล้องกับแถวที่แตกต่างกันของ dataframe ดั้งเดิม

เป้าหมายสุดท้ายคือการส่งออกไปยังไฟล์ .json ซึ่งจะมีรูปแบบ:

{"data": [{row1}, {row2}, ..., {row12}]}

รหัสที่ฉันใช้อยู่ในขณะนี้มีดังต่อไปนี้:

val best_12_struct = best_12.withColumn("data", array((0 to 11).map(i => struct(col("ast"), col("blk"), col("dreb"), col("fg3_pct"), col("fg3a"), 
                                                                   col("fg3m"), col("fg_pct"), col("fga"), col("fgm"), 
                                                                   col("ft_pct"), col("fta"), col("ftm"), col("games_played"), 
                                                                   col("seconds"), col("oreb"), col("pf"), col("player_id"), 
                                                                   col("pts"), col("reb"), col("season"), col("stl"), col("turnover"))) : _*))
            
val best_12_data = best_12_struct.select("data")

แต่ array(0 to 11) จะคัดลอกองค์ประกอบเดียวกัน 12 เท่าไปเป็น data ดังนั้น .json ที่ฉันได้รับในที่สุดจึงมี 12 {"data": ...} โดยในแต่ละแถวเดียวกันถูกคัดลอก 12 ครั้ง แทนที่จะเป็นเพียง {"data": ...} หนึ่งรายการที่มี 12 องค์ประกอบ ซึ่งสอดคล้องกับแต่ละแถวของ dataframe ดั้งเดิม


person Fernando García Sanz    schedule 20.10.2020    source แหล่งที่มา
comment
คุณสามารถเพิ่มข้อมูลตัวอย่างและเอาต์พุตที่คาดหวังใน json ได้ไหม   -  person Srinivas    schedule 21.10.2020


คำตอบ (1)


คุณมีแถวเดียวกัน 12 เท่าเนื่องจากวิธีที่ withColumn จะเลือกข้อมูลจากแถวที่ได้รับการปฏิบัติในปัจจุบันเท่านั้น

คุณต้องรวมแถวที่ระดับ dataframe ด้วย collect_list ที่เป็น ฟังก์ชันรวม ดังต่อไปนี้:

import org.apache.spark.sql.functions._

val best_12_data = best_12
  .withColumn("row", struct(col("ast"), col("blk"), col("dreb"), col("fg3_pct"), col("fg3a"), col("fg3m"), col("fg_pct"), col("fga"), col("fgm"), col("ft_pct"), col("fta"), col("ftm"), col("games_played"), col("seconds"), col("oreb"), col("pf"), col("player_id"), col("pts"), col("reb"), col("season"), col("stl"), col("turnover")))
  .agg(collect_list(col("row")).as("data"))
person Vincent Doba    schedule 21.10.2020