如何避免将新行计为spark中的单词?

时间:2015-08-18 06:54:57

标签: python regex apache-spark

我试图在lorem ipsum上运行单词计数示例;即计算给定文本文件中的单词频率。作为单词拆分的规则,我想使用任何非字符的实例。我有以下python代码:

import re
from pyspark import SparkContext
print "-----------------===========================-----------------"
print "-----------------==========Staring==========-----------------"
print "-----------------===========================-----------------"
sc = SparkContext(appName = "simple app")

print "-----------------===========================-----------------"
print "-----------------==========Loaded file======-----------------"
print "-----------------===========================-----------------"
text_file = sc.textFile("lorem.txt")

print "-----------------===========================-----------------"
print "-----------------==========  Process  ======-----------------"
print "-----------------===========================-----------------"
counts = text_file.flatMap(lambda line: re.split(r'\W*', line.rstrip())) \
         .map(lambda word: (word, 1)) \
         .reduceByKey(lambda a, b: a + b) \
         .map(lambda (a,b): (b, a)) \
         .sortByKey(False)

output = counts.collect()
counts.saveAsTextFile("test.txt")
sc.stop()
for x in output:
    print (x[0], x[1])

它几乎按预期工作。主要问题是它计算新线。如果我理解正确这是由于正则表达式的工作方式,但我找不到解决方法。我做错了什么?

1 个答案:

答案 0 :(得分:1)

请注意,line.rstrip()仅删除空格。但它可以采用line.rstrip(badchars)中的参数来删除badchars中的所有内容。

即使换行符进入RDD,还有空单词和其他垃圾,您也可以通过在工作流程中添加RDD.filter()步骤来过滤掉它们。 filter为RDD的每个元素调用一个函数,并返回返回true的元素的RDD。

有几种摆脱换行符的方法:

明确地寻找它

counts = text_file.flatMap(lambda line: re.split(r'\W*', line.rstrip())) \
         .filter(lambda word: word!="\n") \
         .map(lambda word: (word, 1)) \
         .reduceByKey(lambda a, b: a + b) \
         .map(lambda (a,b): (b, a)) \
         .sortByKey(False)

过滤字长> 1个字符

counts = text_file.flatMap(lambda line: re.split(r'\W*', line.rstrip())) \
         .filter(lambda word: len(word)>1) \
         .map(lambda word: (word, 1)) \
         .reduceByKey(lambda a, b: a + b) \
         .map(lambda (a,b): (b, a)) \
         .sortByKey(False)