Spark разбить и разобрать JSON в столбце - PullRequest
0 голосов
/ 05 июня 2018

У меня есть фрейм данных PySpark:

catalogid   | 1123798                                                                                                                                                                                                                                                                  
catalogpath | [{"1123798":"Other, poets"},{"1112194":"   Poetry for kids"}

со схемой:

StructType(List(StructField(catalogid,StringType,true),StructField(catalogpath,StringType,true)))

И мне нужно получить только текст (значения) из столбца catalogpath - что-то вроде этого:

catalogid   | 1123798                                                                                                                                                                                                                                                                  
catalog_desc| "Other, poets"; "Poetry for kids"

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Вы можете использовать JSON-анализатор:

import json
from itertools import chain
from pyspark.sql.functions import udf, concat_ws


@udf("array<string>")
def parse(s):
    try:
        return list(chain.from_iterable(x.values() for x in json.loads(s)))
    except:
        pass

df = spark.createDataFrame(
    [(1123798, """[{"1123798":"Other, poets"},{"1112194":"   Poetry for kids"}]""")],
    ("catalogid", "catalogpath")
)

result = df.select("catalogid", parse("catalogpath").alias("catalog_desc"))

result.show(truncate=False)
# +---------+----------------------------------+
# |catalogid|catalog_desc                      |
# +---------+----------------------------------+
# |1123798  |[Other, poets,    Poetry for kids]|
# +---------+----------------------------------+

Если вы хотите одну строку, вы можете применить concat_ws:

result.withColumn("catalog_desc", concat_ws(";", "catalog_desc")).show(truncate=False)
# +---------+-------------------------------+
# |catalogid|catalog_desc                   |
# +---------+-------------------------------+
# |1123798  |Other, poets;   Poetry for kids|
# +---------+-------------------------------+
0 голосов
/ 05 июня 2018

Простая udf функция со строковыми функциями должна помочь вам

import re
from pyspark.sql import functions as f
from pyspark.sql import types as t
def parseString(str):
    return ";".join([re.sub("[}\{]", "", x[x.index(":")+1:]) for x in str.split("},{")])

parseUdf = f.udf(parseString, t.StringType())

df.withColumn('1123798', parseUdf(df['1123798'])).show(truncate=False)

, что должно дать вам

+-----------+----------------------------------+
|catalogid  |1123798                           |
+-----------+----------------------------------+
|catalogpath|"Other, poets";"  Poetry for kids"|
+-----------+----------------------------------+

Надеюсь, ответ полезен

...