Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark 使用reduceByKey函数对文本长度求和时出现Pyspark TypeError_Apache Spark_Pyspark_Rdd - Fatal编程技术网

Apache spark 使用reduceByKey函数对文本长度求和时出现Pyspark TypeError

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'

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

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字符串。