在pyspark中读取json文件

时间:2016-09-10 21:43:56

标签: apache-spark pyspark spark-streaming

我是PySpark的新手,下面是来自kafka的我的JSON文件格式。

{
        "header": {
        "platform":"atm",
        "version":"2.0"
       }
        "details":[
       {
        "abc":"3",
        "def":"4"
       },
       {
        "abc":"5",
        "def":"6"
       },
       {
        "abc":"7",
        "def":"8"
       }    
      ]
    }

如何详细阅读所有"abc" "def"的值,并将其添加到此[(1,2),(3,4),(5,6),(7,8)]之类的新列表中。新列表将用于创建火花数据框。我怎么能在pyspark中做到这一点。我尝试了下面的代码。

parsed = messages.map(lambda (k,v): json.loads(v))
list = []
summed = parsed.map(lambda detail:list.append((String(['mcc']), String(['mid']), String(['dsrc']))))
output = summed.collect()
print output

它会产生错误' 要解压的值太多'

语句summed.collect()下面的错误消息

  

16/09/12 12:46:10 INFO弃用:不推荐使用mapred.task.is.map。   相反,请使用mapreduce.task.ismap 16/09/12 12:46:10 INFO弃用:   不推荐使用mapred.task.partition。相反,使用   mapreduce.task.partition 16/09/12 12:46:10 INFO弃用:   mapred.job.id已弃用。相反,请使用mapreduce.job.id 16/09/12   12:46:10 ERROR执行程序:阶段0.0(TID 1)中任务1.0中的异常   org.apache.spark.api.python.PythonException:Traceback(最近的   最后打电话):文件   " /usr/hdp/2.3.4.0-3485/spark/python/lib/pyspark.zip/pyspark/worker.py" ;,   第111行,主要       process()File" /usr/hdp/2.3.4.0-3485/spark/python/lib/pyspark.zip/pyspark/worker.py",   第106行,正在处理中       serializer.dump_stream(func(split_index,iterator),outfile)文件   " /usr/hdp/2.3.4.0-3485/spark/python/lib/pyspark.zip/pyspark/serializers.py" ;,   第263行,在dump_stream中       vs = list(itertools.islice(iterator,batch))文件"",第1行,在ValueError中:要解压的值太多

4 个答案:

答案 0 :(得分:4)

首先,json无效。标题后面缺少,

话虽如此,让我们拿这个json:

{"header":{"platform":"atm","version":"2.0"},"details":[{"abc":"3","def":"4"},{"abc":"5","def":"6"},{"abc":"7","def":"8"}]}

这可以通过以下方式处理:

>>> df = sqlContext.jsonFile('test.json')
>>> df.first()
Row(details=[Row(abc='3', def='4'), Row(abc='5', def='6'), Row(abc='7', def='8')], header=Row(platform='atm', version='2.0'))

>>> df = df.flatMap(lambda row: row['details'])
PythonRDD[38] at RDD at PythonRDD.scala:43

>>> df.collect()
[Row(abc='3', def='4'), Row(abc='5', def='6'), Row(abc='7', def='8')]

>>> df.map(lambda entry: (int(entry['abc']),     int(entry['def']))).collect()
[(3, 4), (5, 6), (7, 8)]

希望这有帮助!

答案 1 :(得分:0)

根据注释中的信息,消息RDD中的每一行都包含json文件中的一行

 u'{', 
 u' "header": {', 
 u' "platform":"atm",'

您的代码在以下行中失败:

parsed = messages.map(lambda (k,v): json.loads(v))

您的代码如下所示:'{'并尝试将其转换为键,值,并执行json.loads(value)

很明显,python / spark无法将一个char'{'分成键值对。

应该在完整的json数据对象

上执行json.loads()命令

使用纯python

可以更轻松地完成此特定任务

答案 2 :(得分:0)

import pyspark
from pyspark import SparkConf

# You can configure the SparkContext

conf = SparkConf()
conf.set('spark.local.dir', '/remote/data/match/spark')
conf.set('spark.sql.shuffle.partitions', '2100')
SparkContext.setSystemProperty('spark.executor.memory', '10g')
SparkContext.setSystemProperty('spark.driver.memory', '10g')
sc = SparkContext(appName='mm_exp', conf=conf)
sqlContext = pyspark.SQLContext(sc)

data = sqlContext.read.json(file.json)

我觉得他错过了阅读序列的重要部分。您必须初始化一个SparkContext。

启动SparkContext时,它还会在端口4040上启动一个webUI。可以使用http://localhost:4040访问该webUI。这是检查所有计算进度的有用位置。

答案 3 :(得分:0)

尝试使用最新的spark版本。

df = spark.read.json('test.json')