Pyspark将JSON数组转换为数据框行

时间:2020-01-23 19:02:39

标签: python json pyspark

pyspark初学者-我有一个spark数据框,其中每一行都是s3上的url。 每个网址都是JSON数组的GZIP文件,我可以将数据框中的每一行(链接)解析为python列表,但是我不知道如何从此JSON列表中创建多行。

这是我用来返回json列表的函数:

def distributed_read_file(url):
    s3_client = boto3.client('s3')
    result = s3_client.get_object(Bucket=raw_data_bucket_name, Key=url)
    bytestream = BytesIO(result['Body'].read())
    string_json = GzipFile(None, 'rb', fileobj=bytestream).read().decode('utf-8')
    list_of_jsons = json.loads(string_json) 

例如,如果这些是列表中的JSON对象:

[{"a": 99, "b": 102}, {"a": 43, "b": 87}]

我想在URLS数据帧上运行一个函数,例如:

result_df = urls_rdd.map(distributed_read_file)

并获得包含以下列的数据框: a b (JSON键)。 当我尝试执行此操作时,我将每个json对象作为MapType列返回,这对我来说很难。

非常感谢你,我希望这很清楚!

1 个答案:

答案 0 :(得分:1)

因此,如果对某人有所帮助,我发现了一个非常简单的解决方案:

def distributed_read_gzip(url):
    s3_client = boto3.client('s3')
    result = s3_client.get_object(Bucket=raw_data_bucket_name, Key=url)
    bytestream = BytesIO(result['Body'].read())
    string_json = GzipFile(None, 'rb', fileobj=bytestream).read().decode('utf-8')
    for json_obj in json.loads(string_json):
        yield Row(**json_obj)

调用函数时是用平面图完成的,因为每个URL返回几行:

new_rdd = urls_rdd.flatMap(distributed_read_gzip)