Apache spark 使用reduceByKey函数对文本长度求和时出现Pyspark TypeError
我想知道为什么在使用reduceByKey函数计算以下数据中每个给定名称(键)的每个列表中所有字符的总长度时会出现类型错误Apache spark 使用reduceByKey函数对文本长度求和时出现Pyspark TypeError,apache-spark,pyspark,rdd,Apache Spark,Pyspark,Rdd,我想知道为什么在使用reduceByKey函数计算以下数据中每个给定名称(键)的每个列表中所有字符的总长度时会出现类型错误 data = [("Cassavetes, Frank", 'Orange'), ("Cassavetes, Frank", 'Pineapple'), ("Knight, Shirley (I)", 'Apple'), ("Knight, Shirley (I)", 'Blueberries'
data = [("Cassavetes, Frank", 'Orange'),
("Cassavetes, Frank", 'Pineapple'),
("Knight, Shirley (I)", 'Apple'),
("Knight, Shirley (I)", 'Blueberries'),
("Knight, Shirley (I)", 'Orange'),
("Yip, Françoise", 'Grapes'),
("Yip, Françoise", 'Apple'),
("Yip, Françoise", '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','Pear'),('Buck(X)'Kiwi')]
我注意到下面的代码产生了期望的结果
reducedRdd = rdd.reduceByKey( lambda a,b: len(str(a)) + len(str(b)) )
虽然我不确定为什么我需要将变量a和b转换为字符串,如果它们最初是字符串,例如,我不确定如何将中的“橙色”(“Cassavetes,Frank”,“Orange”)视为int
PS我知道我可以使用许多其他功能来实现期望的结果,但是我特别想知道为什么我在尝试使用
reduceByKey
函数时遇到问题。代码中的问题是,传递给reduceByKey
的reduce函数不会产生与RDD值相同的数据类型。lambda函数返回一个int
,而您的值是字符串类型
data = [("Cassavetes, Frank", 'Orange'),
("Cassavetes, Frank", 'Pineapple'),
("Knight, Shirley (I)", 'Apple'),
("Knight, Shirley (I)", 'Blueberries'),
("Knight, Shirley (I)", 'Orange'),
("Yip, Françoise", 'Grapes'),
("Yip, Françoise", 'Apple'),
("Yip, Françoise", 'Strawberries'),
("Danner, Blythe", 'Pear'),
("Buck (X)", 'Kiwi')]
为了理解这一点,简单地考虑减少的工作原理。该函数应用于前2个值,然后将该函数的结果添加到第三个值,依此类推
请注意,即使是为你工作的那个,实际上也不正确。例如,它返回('Danner,Blythe','Pear')
,而不是('Danner,Blythe',4)
应首先将值转换为相应的长度,然后按键减少:
reducedRdd = rdd.mapValues(lambda x: len(x)).reduceByKey(lambda a, b: a + b)
print(reducedRdd.collect())
# [('Cassavetes, Frank', 15), ('Danner, Blythe', 4), ('Buck (X)', 4), ('Knight, Shirley (I)', 22), ('Yip, Françoise', 23)]
如果lambda函数应用于前2个值,那么为什么我将lambda函数更改为
lambda,b:a.upper()+b.upper()
所有归因于“Knight,Shirley(i)”的3个值都应用了上一个函数,而不仅仅是前两个?(如果这可以工作,那么为什么我的原始lambda和len函数(在本例中应用于第三个值)不使用@KvothesLute函数lambda,b:a.upper()+b.upper()
以大写形式返回字符串,并且您正在连接字符串,因此没有问题。在第一个函数中,len(x)
返回一个int-not字符串。