微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 reduceByKey 函数求和文本长度时的 Pyspark TypeError

如何解决使用 reduceByKey 函数求和文本长度时的 Pyspark TypeError

我想知道为什么在使用 reduceByKey 函数在下面的数据中尝试计算每个给定名称(键)的每个列表中所有字符的总长度时出现类型错误

data = [("Cassavetes,Frank",'Orange'),("Cassavetes,'Pineapple'),("Knight,Shirley (I)",'Apple'),'Blueberries'),("Yip,Françoise",'Grapes'),'Strawberries'),("Danner,Blythe",'Pear'),("Buck (X)",'Kiwi')]

为了做到这一点,我尝试执行下面的代码

rdd = spark.sparkContext.parallelize(data)
reducedRdd = rdd.reduceByKey( lambda a,b: len(a) + len(b) )
reducedRdd.collect()

上面产生的代码给了我以下错误

TypeError: 'int' 类型的对象没有 len()

我期望的输出如下;

[('Yip,Françoise',14),('Cassavetes,Frank',15),('Knight,Shirley (I)',8),('Danner,Blythe',( '巴克 (X)','猕猴桃')]

我注意到下面的代码产生了预期的结果;

reducedRdd = rdd.reduceByKey( lambda a,b: len(str(a)) + len(str(b)) )

虽然我不确定为什么我需要将变量 a 和 b 转换为字符串,如果它们最初是字符串开头,例如我不确定 ("Cassavetes,'Orange' in ("Cassavetes,'Orange' ') 可以被认为是一个整数。

PS 我知道我可以使用许多其他函数来达到预期的结果,但我特别想知道为什么我在尝试使用 reduceByKey 函数执行此操作时遇到问题。

解决方法

您代码中的问题是您传递给 reduceByKey 的 reduce 函数产生的数据类型与 RDD 值不同。 lambda 函数返回 int,而您的值属于 string 类型。

要理解这一点,只需考虑 reduce 的工作原理。该函数应用于前 2 个值,然后将函数的结果添加到第三个值,依此类推...

请注意,即使是对您有用的那个实际上也不正确。例如,它返回 ('Danner,Blythe','Pear') 而不是 ('Danner,4)

您应该首先将值转换为其相应的长度,然后按键减少:

reducedRdd = rdd.mapValues(lambda x: len(x)).reduceByKey(lambda a,b: a + b)
print(reducedRdd.collect())
# [('Cassavetes,Frank',15),('Danner,4),('Buck (X)',('Knight,Shirley (I)',22),('Yip,Françoise',23)] 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。