Как выбрать ключи из Json Object {} DataFrame в Spark - PullRequest
0 голосов
/ 19 января 2020

У меня есть строка json как:

{"user_rating": {"rating_text": "Excellent", "rating_color": "3F7E00", "votes": "778", "aggregate_rating": "4.5"}}

Я могу sh создать из нее DataFrame со столбцами DataFrame как:

rating_text | rating_color | votes | aggregate_rating

Когда я кодирую это как:

val pdf = json.select("user_rating")

Я получаю только один столбец user_rating

Я подошел к этому наиболее проголосовавшему решению, но все еще получаю только user_rating колонка: pdf.show()

Не знаю, как точно работает Solution1 .

Solution 1 Solution 2

Невозможно получить доступ к столбцам по индексу, как указано в Solution2 . Получение NoSuchColumn ошибки столбца.


Каков наилучший из возможных подходов для извлечения keys(rating_text,rating_color,..) и использования в качестве столбцов в DataFrame?

Используемый язык: Scala


Попробовал приведенный ниже способ перебирать каждый Row в DataFrame и анализировать, получая столбцы:

val pdf = json.select("restaurants.restaurant.user_rating")
pdf.map{Rrowow => (row.getStruct(0).getString(0))}.show()

Получение исключения ниже при map функция:

 java.lang.ClassCastException: scala.collection.mutable.WrappedArray$ofRef cannot be cast to org.apache.spark.sql.Row

Ответы [ 2 ]

1 голос
/ 19 января 2020

Вы можете проанализировать столбец, содержащий JSON String, и построить кадр данных, содержащий все столбцы в JSON. Вот пример -

    val jsonData = """{"rating_text": "Excellent", "rating_color": "3F7E00", "votes": "778", "aggregate_rating": "4.5"}"""

    val schema = {StructType(
      List(
        StructField("rating_text", StringType, nullable = false),
        StructField("rating_color", StringType, nullable = false),
        StructField("votes", StringType, nullable = false),
        StructField("aggregate_rating", StringType, nullable = false)
      ))}

    val df = spark.createDataset(Seq(jsonData)).toDF("user_rating")
    val dfWithParsedJson = df.withColumn("json_data",from_json($"user_rating",schema))

    dfWithParsedJson.select($"user_rating",$"json_data.rating_text", $"json_data.rating_color",$"json_data.votes",$"json_data.aggregate_rating").show()

Результат -

+--------------------+-----------+------------+-----+----------------+
|         user_rating|rating_text|rating_color|votes|aggregate_rating|
+--------------------+-----------+------------+-----+----------------+
|{"rating_text": "...|  Excellent|      3F7E00|  778|             4.5|
+--------------------+-----------+------------+-----+----------------+

Если json находится в файле, вы можете просто прочитать его как

    //file contains - {"user_rating": {"rating_text": "Excellent", "rating_color": "3F7E00", "votes": "778", "aggregate_rating": "4.5"}}
    val df = spark.read.json("path to test.txt")
    df.select("user_rating.rating_text").show()

Вы можете читать данные из объекта Row, используя такие индексы, как

    df.map{ row =>
      (row.getStruct(0).getString(0))
    }.show()

    //Used getStruct(index) because the data type is a complex class. for ordinary values you can use getString, getLong etc

Я настоятельно рекомендую использовать схему для чтения и работы с json. Это сэкономит вам массу ошибок во время выполнения и намного быстрее.

0 голосов
/ 26 марта 2020

Я получил работу вокруг. В основном я искал функцию explode. Который возвращает строку для каждого элемента в столбце.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...