我正在尝试读取多个JSON来创建DataFrame。
我将多个JSON文件放在一个PythonRDD中,然后当我尝试转换为DataFrame时,它失败了。我使用方法toDF()
或sqlContext.createDataFrame()
我收到以下错误:
ValueError: Some of types cannot be determined by the first 100 rows, please try again with sampling
这很奇怪,因为使用sqlContext.read.json()
可以正常工作。
这是我的代码:
import json
from pyspark.sql import Row
def dict_to_row(obj):
if isinstance(obj, dict) and len(obj.values())>0:
d = {}
for k in obj.keys():
d[k] = dict_to_row(obj[k])
return Row(**d)
elif isinstance(obj, list):
return [dict_to_row(o) for o in obj]
else:
return obj
def distributed_json_read(filename):
jsons = open(filename,'r')
json_list = jsons.readlines()
for e in json_list:
json_row = json.loads(e.rstrip())
yield dict_to_row(json_row)
json_list = ['test1.json','test2.json']
parallel_keys = sc.parallelize(json_list)
data_rdd = parallel_keys.flatMap(distributed_json_read)
df = sqlContext.createDataFrame(data_rdd)
这是test1.json的一个例子:
{
"data": {
"f": {
"a": {
"a1": 100,
"a2": 1
},
"b": [
{
"b1": {
"b11": 1,
"b12": null
},
"date1": "2016-02-05T01:58:04.000-0400",
"b2": {
"b21": null,
"b22": "9ca6d130fddb",
"b23": false
}
}
]
}
},
"id": 1689
}
有人遇到此错误?
实际上我的目标是读取多个可能具有不同模式的JSON文件,但最后构建一个DataFrame,其模式将是JSON模式的并集。与sqlContext.read.json()相似,如果参数是一个内置多个JSON的文件。
答案 0 :(得分:1)
我之前写了一个自定义的json阅读器来获得火花。我在包含json文件的文件夹上使用了sc.wholeTextFiles()或sc.binaryFiles()。
这将给你一个rdd(k,v)(file_url,wholeFile / BinaryFile) 然后你可以在那个rdd
上申请你的平面地图
rdd = sc.wholeTextFiles(“super_folder_containing_jsons”)
data_rdd = rdd.flatMap(distributed_json_read)
df = sqlContext.createDataFrame(data_rdd)
答案 1 :(得分:0)
您可以为数据框提供静态模式(所有类型的超集),或者为代码提供第一个json以及有助于拥有默认模式的所有字段。
当你没有默认模式而你给json(字段较少)时会出现一个问题,以后可能会因为使用新字段读取新的json文件而出现问题。
答案 2 :(得分:0)
Spark中的JSON必须是单行的,即单个JSON文件应该是一行。
scala> final case class Token(id: Int, body: String)
defined class Token
scala> val df = spark.createDataset(Seq(Token(0, "hello"), Token(1, "world")))
df: org.apache.spark.sql.Dataset[Token] = [id: int, body: string]
scala> df.show
+---+-----+
| id| body|
+---+-----+
| 0|hello|
| 1|world|
+---+-----+
scala> df.write.json("so.json")
// $ cat so.json/part-r-00003-469964b4-aaf8-4c7a-8f8a-d76c08e792ce.json
// {"id":0,"body":"hello"}