apache-spark - 根据 PySpark 中值的相似性减少键值对
问题描述
我是 PySpark 的初学者。
我想找到值中具有相同数字的字母对,然后找出哪对字母出现的频率更高。
这是我的数据
data = sc.parallelize([('a', 1), ('b', 4), ('c', 10), ('d', 4), ('e', 4), ('f', 1), ('b', 5), ('d', 5)])
data.collect()
[('a', 1), ('b', 4), ('c', 10), ('d', 4), ('e', 4), ('f', 1), ('b', 5), ('d', 5)]
我想要的结果是这样的:
1: a,f
4: b, d
4: b, e
4: d, e
10: c
5: b, d
我尝试了以下方法:
data1= data.map(lambda y: (y[1], y[0]))
data1.collect()
[(1, 'a'), (4, 'b'), (10, 'c'), (4, 'd'), (4, 'e'), (1, 'f'), ('b', 5), ('d', 5)]
data1.groupByKey().mapValues(list).collect()
[(10, ['c']), (4, ['b', 'd', 'e']), (1, ['a', 'f']), (5, ['b', 'd'])]
正如我所说,我对 PySpark 很陌生,并试图搜索该命令但没有成功。谁能帮我解决这个问题?
解决方案
您可以使用flatMap
pythonitertools.combinations
从分组值中获取 2 的组合。此外,更喜欢使用reduceByKey
而不是groupByKey
:
from itertools import combinations
result = data.map(lambda x: (x[1], [x[0]])) \
.reduceByKey(lambda a, b: a + b) \
.flatMap(lambda x: [(x[0], p) for p in combinations(x[1], 2 if (len(x[1]) > 1) else 1)])
result.collect()
#[(1, ('a', 'f')), (10, ('c',)), (4, ('b', 'd')), (4, ('b', 'e')), (4, ('d', 'e')), (5, ('b', 'd'))]
如果你想在元组只有一个元素时得到 None ,你可以使用这个:
.flatMap(lambda x: [(x[0], p) for p in combinations(x[1] if len(x[1]) > 1 else x[1] + [None], 2)])
推荐阅读
- powershell - 超时调用命令
- r - mlr3,基准测试和嵌套重采样:如何从基准对象中提取调整模型以计算特征重要性
- unicode - unicode 异常字符列表
- c - /usr/bin/ld: 找不到 -lgcc
- visual-studio-code - 在启动时配置 Java Runtime VS Code
- rust - How to fix "cannot infer type" error when implementing methods for a generic struct that return specific types?
- docker - 使用视觉工作室的 Docker_error
- android - 无法解析第三方库
- python - 使用 pyodbc 实现 cursor.fast_executemany 的问题
- javascript - 赛普拉斯:可以动态选择带有 eq() 的随机元素吗?