假设我有一个RDD [(String,Int)],如下例所示:
(A, 0)
(B, 0)
(C, 1)
(D, 0)
(E, 2)
(F, 1)
(G, 1)
(H, 3)
(I, 2)
(J, 0)
(K, 3)
我想有效地打印包含0,1,2等的记录总数。 由于RDD包含数百万条目,我希望尽可能高效地完成这项工作。
此示例的输出将返回如下内容:
Number of records containing 0 = 4
Number of records containing 1 = 3
Number of records containing 2 = 2
Number of records containing 3 = 2
目前我尝试通过对大RDD执行过滤,然后count()
分别对0,1,2,...进行实现。我正在使用Scala。
有更有效的方法吗?我已经缓存了RDD,但我的程序仍然没有内存(我已将驱动程序内存设置为5G)。
修改
正如Tzach所建议的,我现在使用countByKey
:
rdd.map(_.swap).countByKey()
我可以通过将字符串值更改为元组(其中第二个元素是" m"或" f")来优化这一点,然后获取每个唯一键的每个键的计数这个元组的第二个元素的值?
例如:
(A,m), 0)
(B,f), 0)
(C,m), 1)
(D,m), 0)
(E,f), 2)
(F,f), 1)
(G,m), 1)
(H,m), 3)
(I,f), 2)
(J,f), 0)
(K,m), 3)
会导致
((0,m), 2)
((0,f), 2)
((1,m), 2)
((1,f), 1)
((2,m), 0)
((2,f), 2)
((3,m), 2)
((3,f), 0)
提前致谢!
答案 0 :(得分:2)
您可以使用方便的countByKey
- 只需事先交换输入中的位置,使数值成为关键:
val rdd = sc.parallelize(Seq(
("A", 0), ("B", 0), ("C", 1), ("D", 0), ("E", 2),
("F", 1), ("G", 1), ("H", 3), ("I", 2), ("J", 0), ("K", 3)
))
rdd.map(_.swap).countByKey().foreach(println)
// (0,4)
// (1,3)
// (3,2)
// (2,2)
编辑:countByKey
完全听起来像 - 所以无论你想使用什么键,只需转换你的RDD就可以将它作为元组的左侧部分,例如:
rdd.map { case ((a, b), i) => ((i, b), a) }.countByKey()
或:
rdd.keyBy { case ((_, b), i) => (i, b) }.countByKey()