PySpark中如何为Filter函数设置范围?代码未达预期求助
问题分析与解决
嘿,我一眼就get到你代码里的问题啦!你猜测的引号方向没错,但核心问题是字符串和数字的比较逻辑完全不一样~
你看,textFile.flatMap(lambda x: x.split(' ')) 拆分出来的每一个x都是字符串类型,而字符串的比较是按字符的ASCII码顺序逐个对比的,不是按数字大小来的。举个例子:字符串"100"和"94"比较时,第一个字符"1"的ASCII码比"9"小,所以"100" <= "94"会返回True,这就导致很多不符合数字大小逻辑的字符串被保留下来了,完全不是你想要的结果。
修正方案
解决思路很简单:先把字符串转换成数字类型,再进行大小判断。不过要注意,如果文本里有非数字的内容,直接转int会报错,所以最好先做个校验。
这里给你两种可行的修正方式:
方式一:先校验是否为数字再转换
# 记得先导入add哦 from operator import add counts = textFile.flatMap(lambda x: x.split(' ')) \ # 先判断x是否是纯数字,再转成int比较 .filter(lambda x: x.isdigit() and int(x) <= 94) \ .map(lambda x: (x, 1)) \ .reduceByKey(add) output = counts.collect() for (word, count) in output: print("%s: %i" % (word, count))
方式二:用try-except处理可能的非数字(更健壮)
如果你的文本里有带符号的数字(比如负号)或者其他特殊情况,isdigit()可能不适用,这时候可以用try-except来捕获转换异常:
from operator import add def is_valid_number_and_le94(s): try: num = int(s) return num <= 94 except ValueError: return False counts = textFile.flatMap(lambda x: x.split(' ')) \ .filter(is_valid_number_and_le94) \ .map(lambda x: (x, 1)) \ .reduceByKey(add) output = counts.collect() for (word, count) in output: print("%s: %i" % (word, count))
这样修改后,就能准确筛选出数字值小于等于94的内容啦!
内容的提问来源于stack exchange,提问作者Kristina
相关产品推荐
相关产品推荐

