【问题标题】:finding top 100 words for each character pyspark为每个字符 pyspark 查找前 100 个单词
【发布时间】:2016-04-13 21:26:35
【问题描述】:

我是 spark 的新手,我的任务是从一组推文中为小字母表中的每个字符获取前一百个单词。例如

a: (word1, count1), (word2, count2).. (word100, count100) 
b: (word1, count1), (word2, count2).. (word100, count100) 
.
.
z: (word1, count1), (word2, count2).. (word100, count100)

这是我的代码:

words_mapped = (en_text.flatMap(lambda x: x.split())
                       .filter(lambda x: x[0] in valid_chars )
                       .map(lambda x: (x[0], x)))

这给出了一个包含字符和单词的元组,现在我必须对这些字符进行分组,并在值中找到每个单词的计数,并显示前 100 个单词及其计数。

我怎样才能把它翻译成 pyspark。

【问题讨论】:

  • 你的“性格”是什么意思
  • @Natecat 我已经更新了问题,小字母的字符,另见示例

标签: python apache-spark lambda pyspark rdd


【解决方案1】:

Spark 使聚合(键、值)对变得容易。在这里,您有两个阶段——在第一阶段,您的关键是(字符,单词),然后在第二阶段,您的关键是(字符)。 (首先,您需要计算计数;其次,您需要找到最重要的计数。)

第一个非常简单,使用reduceByKey (docs)。

words_counted = words_mapped.map( lambda x: (x, 1))
                            .reduceByKey(add)

现在我们需要过滤到前 100 名。这是 Spark 不太擅长的,因为它需要一次处理多行。 Scala 有 TopByKey function,但 PySpark 似乎还不支持。

所以让我们循环遍历字符(至少只有 26 个)并像这样使用takeOrdered (docs):

char = 'a'
charRDD = words_counted.filter(lambda x: x[0][0]==char).takeOrdered(100, key=lambda x: -x[1])

然后您可以根据需要连接这些列表。

一些替代方法:使用partitionBy (docs) 将每个组放在自己的分区中,然后使用mapPartitions (docs) 将每个组的迭代器转换为相关对象(例如,排序然后进入前 100 名)。

使用foldByKey (docs) 的另一种可能性,从一个空列表开始,通过二进制插入将下一个元素添加到列表中,然后删除 100 之后的任何元素。

【讨论】:

  • 是否可以很好地扩展?喜欢循环超过 26 个字符是有意义的,但是例如,如果我们要通过前 100 名海报查找前 1000 个查询,如果我们首先找到前 100 名海报,然后为每个用户一一过滤他们的前 1000 条推文,会不会有问题?
  • @AzeemAkhter 如果缓存 words_counted,它应该是线性缩放的。如果你想要亚线性缩放,你需要做一些更聪明的事情。我将编辑帖子以描述这一点。
猜你喜欢
  • 2013-03-11
  • 1970-01-01
  • 1970-01-01
  • 2015-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-15
相关资源
最近更新 更多