Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PySpark:如何读取多个JSON文件,每个文件有多条记录_Json_Amazon S3_Apache Spark_Pyspark - Fatal编程技术网

PySpark:如何读取多个JSON文件,每个文件有多条记录

PySpark:如何读取多个JSON文件,每个文件有多条记录,json,amazon-s3,apache-spark,pyspark,Json,Amazon S3,Apache Spark,Pyspark,我有一个存储在S3存储桶中的大型数据集,但它不是一个单一的大型文件,而是由许多(确切地说是113K)单独的JSON文件组成,每个文件包含100-1000个观察值。这些观察不是最高级别的,但需要在每个JSON中进行一些导航才能访问。 即 json[“交互”]是一个字典列表 我试图利用Spark/PySpark(版本1.1.1)解析并减少这些数据,但我无法找到将其加载到RDD中的正确方法,因为它既不是所有记录>一个文件(在这种情况下,我会使用sc.textFile,尽管这里增加了JSON的复杂性),

我有一个存储在S3存储桶中的大型数据集,但它不是一个单一的大型文件,而是由许多(确切地说是113K)单独的JSON文件组成,每个文件包含100-1000个观察值。这些观察不是最高级别的,但需要在每个JSON中进行一些导航才能访问。 即 json[“交互”]是一个字典列表

我试图利用Spark/PySpark(版本1.1.1)解析并减少这些数据,但我无法找到将其加载到RDD中的正确方法,因为它既不是所有记录>一个文件(在这种情况下,我会使用sc.textFile,尽管这里增加了JSON的复杂性),也不是每个记录>一个文件(在这种情况下,我会使用sc.wholeTextFiles)

我的最佳选择是使用sc.wholeTextFiles,然后使用map(或者在本例中是flatMap?)将存储在单个文件名键下的多个观测值提取到它们自己的键吗?还是有一种更简单的方法让我错过了


我在这里看到的答案建议在通过sc.textFile加载的所有文件上使用json.loads(),但这似乎不适合我,因为json不是简单的最高级别列表

名称有误导性(因为它是单数的),但是
sparkContext.textFile()
(至少在Scala的情况下)也接受目录名或通配符路径,所以您可以说
textFile(“/my/dir/*.json”)

使用数据帧怎么样

testFrame=sqlContext.read.json('s3n://')
从一个文件中得到你想要的东西

是否每个观察都有相同的“列”(#个键)

如果是这样,您可以使用boto列出要添加的每个对象,读入它们并将它们彼此合并

from pyspark.sql import SQLContext
import boto3
from pyspark.sql.types import *
sqlContext = SQLContext(sc)

s3 = boto3.resource('s3')
bucket = s3.Bucket('<bucket>')

aws_secret_access_key = '<secret>'
aws_access_key_id = '<key>'

#Configure spark with your S3 access keys
sc._jsc.hadoopConfiguration().set("fs.s3n.awsAccessKeyId", aws_access_key_id)
sc._jsc.hadoopConfiguration().set("fs.s3n.awsSecretAccessKey", aws_secret_access_key)
object_list = [k for k in bucket.objects.all() ]
key_list = [k.key for k in bucket.objects.all()]

paths = ['s3n://'+o.bucket_name+'/'+ o.key for o in object_list ]

dataframes = [sqlContext.read.json(path) for path in paths]

df = dataframes[0]
for idx, frame in enumerate(dataframes):
    df = df.unionAll(frame)
从pyspark.sql导入SQLContext
进口boto3
从pyspark.sql.types导入*
sqlContext=sqlContext(sc)
s3=boto3.resource('s3')
bucket=s3.bucket(“”)
aws_secret_access_key=''
aws\u访问\u密钥\u id=“”
#使用S3访问密钥配置spark
sc.(jsc.hadoopConfiguration().set(“fs.s3n.awsAccessKeyId”,aws_access_key_id)
sc._jsc.hadoopConfiguration().set(“fs.s3n.awsSecretAccessKey”,aws_secret_access_key)
object_list=[k代表bucket.objects.all()中的k]
key_list=[k.key代表bucket.objects.all()中的k]
paths=['s3n://'+o.bucket\u name+'/'+o.key用于对象\u列表中的o]
dataframes=[sqlContext.read.json(path)表示路径中的路径]
df=数据帧[0]
对于idx,枚举中的帧(数据帧):
df=df.unionAll(帧)

我是个新手,所以我想知道是否有更好的方法可以将数据帧与许多s3文件一起使用,但到目前为止,这对我来说是可行的。

前面的答案不会以分布式方式读取文件(请参阅)。为此,您需要并行化s3键,然后在下面的flatMap步骤中读入文件

import boto3
import json
from pyspark.sql import Row

def distributedJsonRead(s3Key):
    s3obj = boto3.resource('s3').Object(bucket_name='bucketName', key=s3Key)
    contents = json.loads(s3obj.get()['Body'].read().decode('utf-8'))
    for dicts in content['interactions']
        yield Row(**dicts)

pkeys = sc.parallelize(keyList) #keyList is a list of s3 keys
dataRdd = pkeys.flatMap(distributedJsonRead)

我遇到了类似的问题。请告诉我是否有解决方案。我刚开始尝试pyspark,我在s3中有很多json文件需要分析。TackOverflow是一个问答网站,不是论坛。因此,我们喜欢将积极的回答表述为解决方案,而不是充满问题的喋喋不休的回答。尤其是在响应旧线程时适用,因为OP不太可能让您参与对话。请重新考虑你的回答,如果有必要的话,请注意。