首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PySpark,按键相交

PySpark,按键相交
EN

Stack Overflow用户
提问于 2016-06-08 11:52:19
回答 1查看 3.1K关注 0票数 1

例如,在PySpark中有两个RDD:

代码语言:javascript
运行
复制
((0,0), 1)
((0,1), 2)
((1,0), 3)
((1,1), 4)

第二是

代码语言:javascript
运行
复制
((0,1), 3)
((1,1), 0)

我想要从第一个RDD到第二个RDD的交集。实际上,第二个RDDs必须为第一个RDDs扮演面具的角色。产出应是:

代码语言:javascript
运行
复制
((0,1), 2)
((1,1), 4)

它意味着来自第一个RDD的值,但仅用于第二个RDD的键。这两个RDD的长度是不同的。

我有一些解决办法(必须证明),但如下所示:

代码语言:javascript
运行
复制
rdd3 = rdd1.cartesian(rdd2)
rdd4 = rdd3.filter(lambda((key1, val1), (key2, val2)): key1 == key2)
rdd5 = rdd4.map(lambda((key1, val1), (key2, val2)): (key1, val1))

我不知道这个解决方案有多有效。想听听有经验的星火程序员的意见..。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-08 13:55:49

也许我们不应该把这个过程看作是联接。您不是真的想连接两个数据集,而是要从另一个数据集中减去一个数据集?

我要从你的问题中说出我的假设

  1. 您根本不关心第二个数据集中的值。
  2. 您只希望在第一个数据集中保留键值对出现在第二个数据集中的值。

Idea 1:Cogroup (我认为可能是最快的方法)。它基本上是计算两个数据集的交集。

代码语言:javascript
运行
复制
rdd1 = sc.parallelize([((0,0), 1), ((0,1), 2), ((1,0), 3), ((1,1), 4)])
rdd2 = sc.parallelize([((0,1), 3), ((1,1), 0)])
intersection = rdd1.cogroup(rdd2).filter(lambda x: x[1][0] and x[1][1])
final_rdd = intersection.map(lambda x: (x[0], list(x[1][0]))).map(lambda (x,y): (x, y[0]))

Idea 2:按键减去

代码语言:javascript
运行
复制
rdd1 = sc.parallelize([((0,0), 1), ((0,1), 2), ((1,0), 3), ((1,1), 4)])
rdd2 = sc.parallelize([((0,1), 3), ((1,1), 0)])

unwanted_rows = rdd1.subtractByKey(rdd2)
wanted_rows = rdd1.subtractByKey(unwanted_rows)

我不确定这是不是比你的方法更快。它确实需要两个subtractByKey操作,这可能是缓慢的。此外,此方法不保留顺序(例如,尽管((0, 1), 2)在第一个数据集中居第一位,但在最终数据集中是第二位的)。但我无法想象这有什么关系。

至于哪个更快,我想这取决于你加入卡特西的时间。映射和过滤往往比subtractByKey所需的洗牌操作更快,但当然,cartesian是一个耗时的过程。

不管怎样,我想你可以试试这个方法,看看它是否适合你!

根据RDDs的大小,提供性能改进的侧值。

如果rdd1足够小,可以保存在主内存中,则如果广播它,然后针对它流rdd2,则减法过程可以大大加快。然而,我承认很少会出现这种情况。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37701733

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档