首页 文章

Pyspark:groupby然后计算真值

提问于
浏览
2

我的数据结构是JSON格式:

"header"{"studentId":"1234","time":"2016-06-23","homeworkSubmitted":True}
"header"{"studentId":"1234","time":"2016-06-24","homeworkSubmitted":True}
"header"{"studentId":"1234","time":"2016-06-25","homeworkSubmitted":True}
"header"{"studentId":"1236","time":"2016-06-23","homeworkSubmitted":False}
"header"{"studentId":"1236","time":"2016-06-24","homeworkSubmitted":True}
....

我需要绘制一个直方图,显示家庭作业的数量已提交:对所有stidentId为真 . 我编写的代码使数据结构变得扁平化,因此我的密钥是header.studentId,header.time和header.homeworkSubmitted .

我使用keyBy按studentId分组:

initialRDD.keyBy(lambda row: row['header.studentId'])
              .map(lambda (k,v): (k,v['header.homeworkSubmitted']))
              .map(mapTF).groupByKey().mapValues(lambda x: Counter(x)).collect()

这给了我这样的结果:

("1234", Counter({0:0, 1:3}),
("1236", Counter(0:1, 1:1))

我只需要计数1,可能映射到列表,以便我可以使用matplotlib绘制直方图 . 我不知道如何继续并过滤所有内容 .

编辑:最后我遍历字典并将计数添加到列表中,然后绘制列表的直方图 . 我想知道是否有一种更优雅的方式来完成我在代码中概述的整个过程 .

3 回答

  • 1
    df = sqlContext.read.json('/path/to/your/dataset/')
    df.filter(df.homeworkSubmitted == True).groupby(df.studentId).count()
    

    请注意,如果存在 "header"True 而不是 true ,则它无效JSON

  • 0

    我现在面前没有Spark,虽然我可以在明天编辑 .

    但是,如果我理解这一点,你有三个键值RDD,需要通过homeworkSubmitted = True过滤 . 我认为你把它变成一个数据帧,然后使用:

    df.where(df.homeworkSubmitted==True).count()
    

    如果要根据其他列浏览子集,则可以使用group by operations .

  • 5

    您可以过滤掉false,将其保存在RDD中,然后使用计数器计算True

    initialRDD.filter(lambda row : row['header.homeworkSubmitted'])
    

    另一种解决方案是对布尔值求和

    data = sc.parallelize([('id1',True),('id1',True),
                        ('id2',False),
                        ('id2',False),('id3',False),('id3',True) ])
    
    
    data.reduceByKey(lambda x,y:x+y).collect()
    

    输出

    [('id2', 0), ('id3', 1), ('id1', 2)]
    

相关问题