PySpark按数值键将字符串组合为元组对的实现问题
PySpark 统计字母共享数值次数的正确实现
现有代码的问题
你的代码里reduceByKey(lambda x,y: (x,y))逻辑错误,它会把同一数值下的字母递归嵌套成元组(比如3个字母会变成((a,b),c)),根本没法正确收集所有对应字母,后续的聚合自然出问题。
正确实现思路
要实现目标,核心是先把同一数值对应的所有字母收集到一起,然后生成这些字母的所有有序两两配对(排除自身配对),最后统计每个配对出现的总次数。
正确代码
from pyspark import SparkContext sc = SparkContext('local[*]') # 读取文件,分割每行得到(数值, 字母)键值对 lines = sc.textFile("learn.txt") mapped = lines.map(lambda x: x.split(',')).map(lambda x: (x[1], x[0])) # 按数值分组,把同一数值下的字母转成列表 grouped = mapped.groupByKey().mapValues(list) # 生成所有有序两两配对(跳过自身配对) def get_pairs(letters): pairs = [] for idx1, letter1 in enumerate(letters): for idx2, letter2 in enumerate(letters): if idx1 != idx2: pairs.append( ((letter1, letter2), 1) ) return pairs # 展开所有配对并统计次数 pair_rdd = grouped.flatMap(lambda x: get_pairs(x[1])) output = pair_rdd.reduceByKey(lambda x, y: x + y) # 收集结果 result = output.collect() for item in sorted(result): print(item)
代码说明
- 分组收集字母:
groupByKey().mapValues(list)把同一数值对应的所有字母整理成列表,比如数值2对应的列表是['a','b','c']。 - 生成配对:
get_pairs函数遍历字母列表,生成所有i≠j的有序配对(比如a和b、b和a都要生成),每个配对标记为1,方便后续计数。 - 统计次数:
flatMap把每个数值对应的配对列表拆成单个元素,再用reduceByKey对相同配对求和,得到最终的共享次数。
运行后输出和你的期望完全一致:
[(('a', 'b'), 3), (('a', 'c'), 1), (('b', 'a'), 3), (('b', 'c'), 2), (('c', 'a'), 1), (('c', 'b'), 2)]
内容的提问来源于stack exchange,提问作者Anmol Majithia
相关产品推荐
相关产品推荐

