将单行文件中的多个JSON对象加载到PySpark时为空值

将单行文件中的多个JSON对象加载到PySpark时为空值,json,amazon-s3,pyspark,pyspark-sql,Json,Amazon S3,Pyspark,Pyspark Sql,我需要一些帮助来将一系列JSON文件从S3存储桶中获取到PySpark数据帧中 这个bucket中的文件都有一个.json扩展名,但不幸的是,它们不符合通常的Spark要求,即每行有一个json对象,相反,它们都在方括号内的一行上 因此,不是: {"first_column": 12, "second_column": {"nested_column": "value"}} {"first_column": 24, "second_column": {"nested_column": "valu

我需要一些帮助来将一系列JSON文件从S3存储桶中获取到PySpark数据帧中

这个bucket中的文件都有一个
.json
扩展名,但不幸的是,它们不符合通常的Spark要求,即每行有一个json对象,相反,它们都在方括号内的一行上

因此,不是:

{"first_column": 12, "second_column": {"nested_column": "value"}}
{"first_column": 24, "second_column": {"nested_column": "value2"}}
我有:

[{"first_column": 12, "second_column": {"nested_column": "value"}},{"first_column": 24, "second_column": {"nested_column": "value2"}}]
我们实际上收到了这种格式的文件,而且文件太多了,很遗憾,进行任何手动调整都是不可行的

到目前为止,我尝试的方法如下:

dfRDD = sc.wholeTextFiles("s3://path_to_bucket_*.json")
我尝试使用
spark.read.json
方法,使用以下语法和通配符
*
一次加载多个文件。在本例中,
spark
sqlContext

df = spark.read.json("s3://path_to_bucket_*.json") 
这将在不引发任何错误或警告的情况下运行,并返回所需的架构:

df.printSchema()

root
 |-- first_column: long (nullable = true)
 |-- second_column: struct (nullable = true)
 |     |-- nested_column: string (nullable = true)
但是,当我尝试查看数据时,我得到以下信息:

+------------+-------------+
|first_column|second_column|
+------------+-------------+
|        null|         null|
+------------+-------------+
我发现了一种从Datatricks中实际加载数据的方法,它使用Spark上下文
sc
读取成对RDD,如下所示:

dfRDD = sc.wholeTextFiles("s3://path_to_bucket_*.json")
这将返回一个带有文件名和文件体的PairedRDD。然而,真正让我不感到困惑的是,当我使用此RDD中的主体信息调用以下行时,它工作正常,并且根本没有空值:

df = spark.read.json(dfRDD.map(lambda x: x[1]))
因此,我对为什么会发生这种情况感到非常困惑,因为我本以为这与输入函数的信息相同,因为RDD中的文本体不包含任何换行符,而是包含方括号内的JSON对象(如上面所示的第二个示例)

虽然这是一个解决办法,但不幸的是缺乏;首先,使用RDD方法要慢得多,而且更重要的是,我需要获得一列文件名,我从中获取这些信息。我知道,当直接从文件加载时,可以使用
pyspark.sql.functions
模块中的
input\u file\u name
函数实现这一点,但在使用RDD方法时,这不起作用。我已经成功地编写了一个纯Python函数,将每个pairedRDD的第一个元素中的文件名信息获取到JSON字符串中,但是速度非常慢


如果有人能帮我解决这个问题,我将非常感激。我理解我可能必须使用RDD方法,但我不明白为什么
spark.read.json
在一种情况下能完美工作,而在另一种情况下却不能。

虽然我不确定是什么原因导致一种解决方案工作,而另一种解决方案不工作,但在某种程度上,我能够通过使用sql.read.json解决问题

将read.json中的参数allowComments、AllowUnnotedFieldNames、allowSingleQuotes、allowNumericLeadingZero、allowBackslashEscapingAnyCharacter设置为True。这样,我就能够删除空值,并且90%的数据在没有任何空值的数据帧中成功转换


请查看其他参数

很抱歉延迟对此的响应。我现在刚刚尝试实现它,但不幸的是,我仍然得到空记录。然而,我注意到另一个可能导致问题的问题。当将
模式
参数设置为
'FAILFAST'
时,由于文本中的某些字符,我还收到一个unicode错误。但是,当使用
wholeTextFiles
方法时,不会出现这种情况。我现在想知道这是否会导致任何其他问题。是的,可能是由于wholeTextFiles忽略了这些字符,记录被声明为已损坏。尝试删除字符一次。我认为这应该行得通。