【发布时间】:2018-05-07 17:04:10
【问题描述】:
如何检查 JSON 文件是否损坏,例如缺少 {、}、逗号或错误的数据类型。我试图通过使用累加器来实现,因为进程在多个执行器上运行。
spark_config = SparkConf().setAppName(application_name)
ss = SparkSession.builder.config(conf=spark_config).getOrCreate()
class StringAccumulatorParam(AccumulatorParam):
def zero(self, v):
return []
def addInPlace(self, variable, value):
variable.append(value)
return variable
errorCount = ss.sparkContext.accumulator(0)
errorValues = ss.sparkContext.accumulator("", StringAccumulatorParam())
newSchema = StructType([
StructField("id", IntegerType(), True),
StructField("name", StringType(), True)
StructField("status", BooleanType(), True)])
errorDF = ss.read.json("/Users/test.jsonl")
errorDF2 = ss.createDataFrame(errorDF, newSchema).cache()
def checkErrorCount(row):
global errorCount
errorDF2["id"] = row. newSchema["id"]
errorCount.add(1)
errorValues.add(errorDF2["id"])
errorDF.foreach(lambda x: checkErrorCount(x))
print("{} rows had questionable values.".format(errorCount.value))
ss.stop()
这是损坏的 JSON 文件 -
{"name":"Standards1","id":90,"status":true}
{"name":"Standards2","id":91
{"name":"Standards3","id":92,"status":true}
{"name":781,"id":93,"status":true}
【问题讨论】:
-
我可能会将文件加载为文本文件。然后编写一个用户定义函数 (udf) 来尝试将每个文本行转换为 JSON。如果成功则输出0,否则输出1。然后对结果求和。
-
另一种选择是读取文件两次。一次作为文本获取总行数。然后再次作为带有选项 mode=DROPMALFORMED 的 json 来获得有效计数。区别在于坏行的数量。
-
谢谢。我有 40 多个良好大小 (MB) 的文件,因此阅读它们两次将超过我们完成工作的时间限制。我曾尝试使用“FAILFAST”,但由于多个执行者的作业我无法捕获异常。有没有办法只获取坏行的数量?
-
如何将每个文本行转换为 JSON。我已经尝试过 textFile("/path/filename.jsonl") 但如何在 Python Spark (PySpark) 中将此 texFile 解析为 JSON。
标签: python json apache-spark pyspark accumulator