将函数映射到Spark中的ResultIterable

时间:2017-05-11 04:31:51

标签: apache-spark pyspark

我有这样的数据集。

rdd = sc.parallelize((('A',('a',1)),('B',('b',3)),('A',('c',3))))

我想做的是:

  1. 计算属于A / B组的条目数。

  2. 在每个组(A / B)中,计算条目属于每个子组的方式(即'a','b','c')。

  3. 如上例所示,我想得到的答案是:

    • 组'A':2
      • 子组'a':1
      • subGroup'c':1
    • 组'B':1
      • 子组'b':1

    我可以通过

    获得第一级结果
    rdd.countByKey()
    

    返回

    defaultdict(<type 'int'>, {'A': 2, 'B': 1})
    

    但我怎么能得到二级结果?

    如果我按

    分组数据
    rdd.groupByKey()
    

    如何将功能映射到每个组中的数据,例如map groupByKey?我注意到结果的值是

    pyspark.resultiterable.ResultIterable
    

    无法应用groupBy或map。

2 个答案:

答案 0 :(得分:0)

喜欢这个吗?

` val rdd = sc.parallelize(Seq(('A',('a',1)),('B',('b',3)),('A',('c',3)) ))

val groups = rdd.groupByKey

grouped.map(x =&gt;(s“\ nTopLevel $ {x._1}:$ {x._2.size} \ nSubLevel $ {x._2.groupBy(i =&gt; i。 1).mapValues( .size)}“))。收集 `

enter image description here

答案 1 :(得分:0)

这是一步一步的解决方案。

from collections import Counter

rdd = sc.parallelize((('A',('a',1)),('B',('b',3)),('A',('c',3))))
# [('A', ('a', 1)), ('B', ('b', 3)), ('A', ('c', 3))]

a = rdd.groupByKey().mapValues(list) 
#[('A', [('a', 1), ('c', 3)]), ('B', [('b', 3)])]

b = a.map(lambda line: line[1])
# [[('a', 1), ('c', 3)], [('b', 3)]]

c = b.map(lambda line: [x[0] for x in line])
# [['a', 'c'], ['b']]

d = c.map(lambda line: Counter(line))
# [Counter({'a': 1, 'c': 1}), Counter({'b': 1})]

如果你想在groupByKey()应用程序之后有一个值列表,你可以使用 mapValues(list)

如果要映射存储在名为&#39; d&#39;的RDD中的信息。 (在这种情况下为[Counter({'a': 1, 'c': 1}), Counter({'b': 1})]),您可以看到此docs并执行:

e = d.map(lambda line: list(line.elements()))
# [['a', 'c'], ['b']]
f = d.map(lambda line: list(line.values()))
# [[1, 1], [1]]