Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.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
Apache spark 如何将PythonRDD(JSON中的行)转换为数据帧?_Apache Spark_Pyspark_Apache Spark Sql - Fatal编程技术网

Apache spark 如何将PythonRDD(JSON中的行)转换为数据帧?

Apache spark 如何将PythonRDD(JSON中的行)转换为数据帧?,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,我试图读取多个JSON来创建一个数据帧 我将多个JSONs文件放在一个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

我试图读取多个JSON来创建一个数据帧

我将多个JSONs文件放在一个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
}
有人经历过这个错误吗


实际上,我的目标是读取多个JSONs文件,这些文件可以具有不同的模式,但最终构建一个数据框架,其模式将是JSONs模式的联合。与使用sqlContext.read.json()可以实现的类似,如果参数是一个包含多个json的文件。

您可以为数据帧提供静态模式(所有类型的超集),或者为代码提供第一个json和所有字段,这将有助于拥有默认模式


一个问题当您没有默认模式并提供json(字段较少)时,以后读取带有新字段的新json文件时可能会出现问题。

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"}

我以前为spark编写过一个自定义json阅读器。我在包含json文件的文件夹中使用了sc.wholeTextFiles()或sc.binaryFiles()

这将为您提供一个rdd(k,v)(文件url,wholeFile/BinaryFile) 然后你可以在rdd上应用你的平面图


rdd=sc.wholeTextFiles(“包含JSON的超级文件夹”)
数据rdd=rdd.flatMap(分布式json读取)

df=sqlContext.createDataFrame(data_rdd)

实际上json是一行,我只是简单地说了一下。我不确定你的解决方案是否有效,因为如果你在flatMap(例如)中使用一个函数,你就没有访问sc(SparkContext)的权限。是的,同意,你不需要在分布式json读取或dict to行中使用sc,使用这个解决方案。我事先就知道全局模式,但是当Spark试图构建最终的RDD时,如果两个或更多JSON没有相同的模式,似乎就会失败。我有点困惑。为什么要创建行而不是直接读取JSON?嗨@zero323我的最终目标是从不同的S3存储桶读取JSON。我想并行读取它们,这就是为什么我不能使用read.json()函数的原因