Извлеките все ключи из объекта Json из таблицы oop, используя Python Spark - PullRequest
3 голосов
/ 30 января 2020

У меня есть oop таблица с именем table_with_json_string

например:

+-----------------------------------+---------------------------------+
|      creation_date                |        json_string_colum        |
+-----------------------------------+---------------------------------+
| 2020-01-29                        |  "{keys : {1 : 'a', 2 : 'b' }}" |
+-----------------------------------+---------------------------------+

желаемый вывод:

+-----------------------------------+----------------------------------+----------+
|      creation_date                |         json_string_colum        |   keys   |
+-----------------------------------+----------------------------------+----------+
| 2020-01-29                        |  "{keys : {1 : 'a', 2 : 'b' }}"  |    1     |
| 2020-01-29                        |  "{keys : {1 : 'a', 2 : 'b' }}"  |    2     |
+-----------------------------------+----------------------------------+----------+

Я пытался:

from pyspark.sql import functions as sf
from pyspark.sql import types as st

from pyspark.sql.functions import from_json, col,explode
from pyspark.sql.types import StructType, StructField, StringType,MapType

schema = StructType([StructField("keys",
                    MapType(StringType(),StringType()),True)])
df = spark.table('table_with_json_string').select(col("creation_date"),col("json_string_colum"))
df = df.withColumn("map_json_column", from_json("json_string_colum",schema))
df.show(1,False)
+--------------------+-------------------------------------+----------------------------------+
|       creation_date|        json_string_colum            |    map_json_column               |
+--------------------+-------------------------------------+----------------------------------+
|   2020-01-29       |     "{keys : {1 : 'a', 2 : 'b' }}"  |    [Map(1 ->'a',2 ->'b')]        |
+--------------------+-------------------------------------+----------------------------------+

1 - Как я могу получить ключи от этого MapType объекта? Я понимаю, что мне нужно использовать функцию explode, чтобы достичь желаемого формата таблицы, но я все еще не знаю, как извлечь ключи объекта JSON в формат массива.

I Я открыт для других подходов, если мне легче достичь цели.

1 Ответ

3 голосов
/ 30 января 2020

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

from pyspark.sql import functions as f
df = (df
 .withColumn("map_json_column", f.from_json("json_string_colum",schema))
 .withColumn("keys", f.map_keys("map_json_column.keys"))
 .drop("map_json_column")
 .withColumn("keys", f.explode("keys"))
 )

Результаты:

+-------------+--------------------+----+
|creation_date|   json_string_colum|keys|
+-------------+--------------------+----+
|   2020-01-29|{"keys" : {"1" : ...|   1|
|   2020-01-29|{"keys" : {"1" : ...|   2|
+-------------+--------------------+----+

Вот подробные инструкции на ответ выше:

>>> from pyspark.sql import functions as f
>>> df.show()
+-------------+--------------------+
|creation_date|   json_string_colum|
+-------------+--------------------+
|   2020-01-29|{"keys" : {"1" : ...|
+-------------+--------------------+

>>> df.withColumn("map_json_column", f.from_json("json_string_colum",schema)).show()
+-------------+--------------------+------------------+
|creation_date|   json_string_colum|   map_json_column|
+-------------+--------------------+------------------+
|   2020-01-29|{"keys" : {"1" : ...|[[1 -> a, 2 -> b]]|
+-------------+--------------------+------------------+

>>> df.withColumn("map_json_column", f.from_json("json_string_colum",schema)).withColumn("keys", f.map_keys("map_json_column.keys")).show()
+-------------+--------------------+------------------+------+
|creation_date|   json_string_colum|   map_json_column|  keys|
+-------------+--------------------+------------------+------+
|   2020-01-29|{"keys" : {"1" : ...|[[1 -> a, 2 -> b]]|[1, 2]|
+-------------+--------------------+------------------+------+

>>> df.withColumn("map_json_column", f.from_json("json_string_colum",schema)).withColumn("keys", f.map_keys("map_json_column.keys")).drop("map_json_column").show()
+-------------+--------------------+------+
|creation_date|   json_string_colum|  keys|
+-------------+--------------------+------+
|   2020-01-29|{"keys" : {"1" : ...|[1, 2]|
+-------------+--------------------+------+

>>> df.withColumn("map_json_column", f.from_json("json_string_colum",schema)).withColumn("keys", f.map_keys("map_json_column.keys")).drop("map_json_column").withColumn("keys", f.explode("keys")).show()
+-------------+--------------------+----+
|creation_date|   json_string_colum|keys|
+-------------+--------------------+----+
|   2020-01-29|{"keys" : {"1" : ...|   1|
|   2020-01-29|{"keys" : {"1" : ...|   2|
+-------------+--------------------+----+

Для ясности, функция map_keys, которую я использую выше, доступна в PySpark 2.3 +

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