【问题标题】:% wordcount in SPARK STREAMING (PYTHON)SPARK STREAMING (PYTHON) 中的 % 字数
【发布时间】:2016-12-14 10:35:35
【问题描述】:

在下一个示例中,我从 Kafka 接收到一个序列词:

('cat')
('dog')
('rat')
('dog')

我的目标是计算每个单词的历史百分比。我将有两个 RDD,一个带有历史字数,另一个带有所有单词的总数:

values = KafkaUtils.createDirectStream(ssc, [topic], {"metadata.broker.list": brokers})


def updatefunc (new_value, last_value):
    if last_value is None:
        last_value = 0
    return sum(new_value, last_value)


words=values.map(lambda x: (x,1)).reduceByKey(lambda a,b: a+b)

historic= words.updateStateByKey(updatefunc).\
    transform(lambda  rdd: rdd.sortBy(lambda (x,v): x))

totalNo = words.\
    map(lambda x: x[1]).reduce(lambda a,b:a+b).map(lambda x: (('totalsum',x))).updateStateByKey(updatefunc).map(lambda x:x[1])

现在我正在尝试除以:((每个键的历史值)/totalNo)*100 来获得每个单词的百分比:

solution=historic.map(lambda x: x[0],x[1]*100/totalNo)

但我得到了错误:

 It appears that you are attempting to reference SparkContext from a broadcast variable, action, or transforamtion. SparkContext can only be used on the driver, not in code that it run on workers. For more information, see SPARK-5063

如何修复totalNO 的值,以便在另一个RDD 中使用它?

【问题讨论】:

    标签: python apache-spark pyspark spark-streaming word-count


    【解决方案1】:

    最后这个方法也可以了:

    words = KafkaUtils.createDirectStream(ssc, topics=['test'], kafkaParams={'bootstrap.servers': 'localhost:9092'})\
        .map(lambda x: x[1]).flatMap(lambda x: list(x))
    
    historic = words.map(lambda x: (x, 1)).updateStateByKey(lambda x, y: sum(x) + (y or 0))
    
    def func(rdd):
        if not rdd.isEmpty():
            totalNo = rdd.map(lambda x: x[1]).reduce(add)
            rdd = rdd.map(lambda x: (x[0], x[1] / totalNo))
        return rdd
    
    solution = historic.transform(func)
    
    solution.pprint()
    

    这是你想要的吗?

    【讨论】:

    • 我想你代码中的 rddQueue1 是 = KafkaUtils.createDirectStream(ssc, [topic], {brokers...})。我正在运行 1.6 版本,所以我会在几分钟内尝试让您知道。谢谢!
    • 确实,我尝试使用:" def func(a,b): return a.cartesian(b) solution=history.transformWith(func(historic,totalNo))" 我得到错误: "AttributeError: 'TransformedDStream' 对象没有属性 'cartesian'"。
    • 我认为解决方案是克隆历史 rdd 并与 totalNo 的 updatefunction 共享状态。并加入历史 rdd 和历史克隆,并用 reducebyKey(lambda a,b: a*100/b) 划分。但我不知道如何使用 updatestatbykey 分享他的状态
    • @epic_last_song 在你尝试之后,它应该是 "def func(a, b): return a.cartesian(b) # solution =history.transformWith(func, totalNo)" 。
    • 我总是得到 ('cat',0),('dog',0),('rat',0)。此外,我正在尝试将历史记录拆分为 2,其中一个具有键值,另一个具有键总计,然后加入 rdds 和 reducebykey(lambda a,b:a/b) 但也不分割。我们非常接近!
    猜你喜欢
    • 2014-09-06
    • 2018-05-23
    • 2014-09-11
    • 2020-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-07
    • 2020-09-28
    相关资源
    最近更新 更多