Получите все значения независимо от ключей из столбца типа JSON в кадре данных Spark, используя Spark с scala - PullRequest
2 голосов
/ 28 мая 2020

Я пытался загрузить файл TSV, содержащий некоторые метаданные о фильмах, используя Spark, этот файл TSV содержит информацию о жанрах фильмов в формате JSON [последний столбец в каждой строке]

Образец Файл

975900  /m/03vyhn   Ghosts of Mars  2001-08-24  14010832    98.0    {"/m/02h40lc": "English Language"}  {"/m/09c7w0": "United States of America"}   {"/m/01jfsb": "Thriller", "/m/06n90": "Science Fiction", "/m/03npn": "Horror", "/m/03k9fj": "Adventure", "/m/0fdjb": "Supernatural", "/m/02kdv5l": "Action", "/m/09zvmj": "Space western"}
3196793 /m/08yl5d   Getting Away with Murder: The JonBenét Ramsey Mystery   2000-02-16      95.0    {"/m/02h40lc": "English Language"}  {"/m/09c7w0": "United States of America"}   {"/m/02n4kr": "Mystery", "/m/03bxz7": "Biographical film", "/m/07s9rl0": "Drama", "/m/0hj3n01": "Crime Drama"}

Я пробовал приведенный ниже код, который позволяет мне получить доступ к определенному значению из жанра JSON

val ss = SessionCreator.createSession("DataCleaning", "local[*]")//helper function creates a spark session and returns it
val headerInfoRb = ResourceBundle.getBundle("conf.headerInfo")
val movieDF = DataReader.readFromTsv(ss, "D:/Utility/Datasets/MovieSummaries/movie.metadata.tsv")
                .toDF(headerInfoRb.getString("metadataReader").split(',').toSeq:_*)//Datareader.readFromTsv is a helper function to read TSV file ,takes sparkSession and file path as input to resurn a dataframe, which uses sparkSession's read function 

movieDF.select("wiki_mv_id","mv_nm","mv_genre")
                .withColumn("genre_frmttd", get_json_object(col("mv_genre"), "$./m/02kdv5l"))
                .show(1,false)

Вывод

+----------+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+
|wiki_mv_id|mv_nm         |mv_genre                                                                                                                                                                                  |genre_frmttd|
+----------+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+
|975900    |Ghosts of Mars|{"/m/01jfsb": "Thriller", "/m/06n90": "Science Fiction", "/m/03npn": "Horror", "/m/03k9fj": "Adventure", "/m/0fdjb": "Supernatural", "/m/02kdv5l": "Action", "/m/09zvmj": "Space western"}|Action      |
+----------+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+
only showing top 1 row

Мне нужен столбец genre_frmttd, как показано ниже, для каждой строки в кадре данных [фрагмент ниже для первой строки образца]

[Thriller,Fiction,Horror,Adventure,Supernatural,Action,Space Western]

Я немного ладья ie в scala и искра, предлагаю какой-нибудь способ перечислить значения

1 Ответ

3 голосов
/ 28 мая 2020
  1. проанализируйте JSON, используя from_json
  2. , приведите его к MapType(StringType, StringType)
  3. извлеките только значения, используя map_values
import org.apache.spark.sql.functions._
import org.apache.spark.sql.types.{MapType, StringType}

movieDF.select("wiki_mv_id","mv_nm","mv_genre")
      .withColumn("genre_frmttd",map_values(from_json(col("mv_genre"),MapType(StringType, StringType))))
      .show(1,false)
...