我正在使用Spark RDD和DataFrame创建文本文件的字数统计,但答案略有不同。我正在使用的数据在这里可用。为什么答案不同?
from pyspark.sql.functions import col, trim, lower, regexp_replace, explode, split, length
from pyspark.sql import Row
from nltk.corpus import stopwords
stopwords = stopwords.words('english')
def clean1(line):
return trim(lower(regexp_replace(line, '[^a-zA-Z0-9\s]','')))
df1 = (spark.read.text("Quran.txt")
.select(clean1('value').alias('line'))
.select(explode(split('line', ' ')).alias('word'))
.filter(length(col("word")) > 0)
.filter(~col('word').isin(stopwords))
.groupBy('word').count()
.orderBy('count', ascending = False)
)
df1.show(10)
import re
def cleanline(line):
return re.sub('[^a-zA-Z0-9\s]', '', line).lower().strip()
df2 = (sc.textFile('Quran.txt')
.map(lambda x: cleanline(x))
.flatMap(lambda x: x.split(' '))
.filter(lambda x: len(x) > 0)
.filter(lambda x: x not in stopwords)
.map(lambda x: (x, 1))
.reduceByKey(lambda a, b: a + b)
.sortBy(lambda x: -x[1])
.map(lambda x: Row(word = x[0], count = x[1]))
.toDF()
.select(['word','count'])
)
df2.show(10)
我发现,如果我将DataFrame部分中的正则表达式从“ [^ a-zA-Z0-9 \ s]”更改为“ [^ a-zA-Z0-9]”,答案将相同。这两个正则表达式模式不一样吗?
如果看一下函数的定义 trim
'ltrim': 'Trim the spaces from left end for the specified string value.',
'rtrim': 'Trim the spaces from right end for the specified string value.',
'trim': 'Trim the spaces from both ends for the specified string column.',
表示修剪只删除空格,不删除制表符(\ t)。但是下面的某些行中有一些选项卡,这些选项卡并未按trim
功能删除。
God could destroy him if He chose, v. 19 (488)
那就是god
上面一行中没有制表符的原因,因此不计在内。而strip
()函数取出所有的空间,包括在前面的标签。
其他计数也是如此。
所以定义udf
,其中函数strip
()Python函数可以用来为您的解决方案。
from pyspark.sql import functions as F
from pyspark.sql import types as T
def stripUdf(x):
return x.strip()
callStripUdf = F.udf(stripUdf, T.StringType())
def clean1(line):
return callStripUdf(F.trim(F.lower(F.regexp_replace(line, '[^a-zA-Z0-9\s]',''))))
现在,正如您提到的那样,从更改[^a-zA-Z0-9\s]
为[^a-zA-Z0-9 ]
解决了该问题,这是因为\ s表示包括制表符(\ t)在内的所有空格,因此应用更改将制表符替换为空字符。trim
我希望答案是有帮助的
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句