PySpark处理鸢尾花数据集RDD时,两个逻辑相近的萼片长度计算函数为何一正常一报错?
分析鸢尾花RDD数据处理函数的报错问题
我来帮你拆解第二个函数的错误原因,其实问题出在reduce的累积逻辑和函数返回值类型不一致上:
先看你报错的getSapellen2函数逻辑:
- 当输入的字符串包含"Sepal"(也就是数据集的表头行,比如
SepalLength,SepalWidth,...)时,直接返回原字符串 - 其他数据行则分割后把第一列转成float返回
而RDD的reduce是逐步累积计算的:第一次会拿RDD里的前两个元素计算——假设第一个元素是表头字符串,第二个是数据行,这时候getSapellen2(表头)返回的是字符串,getSapellen2(数据行)返回的是float,你要把字符串和float相加,自然就触发了TypeError: can only concatenate str (not "float") to str的错误。
再对比第一个能正常运行的getSapellen函数:
- 它遇到表头行时,
attlist[0]是SepalLength,你的is_float判断会返回false,所以函数返回0.0(float类型) - 第一次reduce的时候是0.0 + 第一个数据的float,之后累积的结果都是float,后续每次计算时x都是float,直接返回x,y是数据行转成的float,全程都是同类型运算,所以不会报错。
给你两个修正方案:
方案1:先过滤掉表头行(推荐)
既然表头行不需要参与计算,直接在处理前过滤掉:
# 先过滤掉表头 filtered_irisRDD = irisRDD.filter(lambda line: not line.startswith("Sepal")) def getSapellen2(str2): attlist = str2.split(",") try: return float(attlist[0]) except (ValueError, IndexError): return 0.0 SepalLenAvg = filtered_irisRDD.reduce(lambda x,y: getSapellen2(x) + getSapellen2(y)) / filtered_irisRDD.count() print(SepalLenAvg)
方案2:修改getSapellen2的表头处理逻辑
把表头行的返回值改成float类型的0.0,而不是原字符串:
def getSapellen2(str2): if str2.find("Sepal") != -1: return 0.0 # 这里改成返回0.0,和数据行的返回类型统一 attlist = str2.split(",") try: # 增加异常处理,避免非数字字符串转float报错 return float(attlist[0]) except ValueError: return 0.0 SepalLenAvg = irisRDD.reduce(lambda x,y: getSapellen2(x) + getSapellen2(y)) / (irisRDD.count() - 1) print(SepalLenAvg)
内容的提问来源于stack exchange,提问作者Prashant Mudgal
相关产品推荐
相关产品推荐

