Scala RDD groupby与所有列

时间:2017-01-13 07:27:27

标签: scala apache-spark rdd scala-collections

我需要获取所有列以及count.In Scala RDD。

Col1 col2  col3 col4
us    A     Q1   10
us    A      Q3   10
us    A      Q2   20
us    B      Q4   10
us    B      Q5   20
uk    A      Q1   10
uk    A      Q3   10
uk    A      Q2   20
uk    B      Q4   10
uk    B      Q5   20

我想要的结果如下:

Col1    col2       col3     col4     count
us         A           Q1       10          3
us         A           Q3      10          3
us         A           Q3      10          3
us         B           Q4      10          2
us         B           Q5      20          2
uk         A           Q1       10          3
uk         A           Q3      10          3
uk         A           Q3      10          3
uk         B           Q4      10          2
uk         B           Q5      20          2

这类似于col1,col2的分组并获取计数。现在我需要col13,col4。

我正在尝试SCALA RDD:

val Top_RDD_1 = RDD.groupBy(f=> ( f._1,f._2 )).mapValues(_.toList)

这会产生

RDD[((String, String), List[(String, String, String, Double, Double, Double)])]

只有(col1,col2),List(col1,col2,col3,col14) 结果如(us,A)List((us,a,Q1,10),(us,a,Q3,10),(us,a,Q2,20))。,,,

如何获取列表计数并访问列表值。

请帮助我激发SCALA RDD代码。

由于 巴拉吉。

2 个答案:

答案 0 :(得分:1)

我无法在一个"扫描"中找到一种方法。对于RDD - 您必须使用reduceByKey计算计数,然后使用join计算原始RDD。为了有效地执行此操作(不会导致重新计算输入),您最好在加入之前输入cache / persist

val keyed: RDD[((String, String), (String, String, String, Int))] = input
  .keyBy { case (c1, c2, _, _) => (c1, c2) }
  .cache()

val counts: RDD[((String, String), Int)] = keyed.mapValues(_ => 1).reduceByKey(_ + _)

val result = keyed.join(counts).values.map {
  case ((c1, c2, c3, c4), count) => (c1, c2, c3, c4, count)
} 

答案 1 :(得分:0)

这是python代码:

sales = [["US","A","Q1", 10], ["US","A","Q2", 20], ["US","B","Q3", 10], ["UK","A","Q1", 10], ["UK","A","Q2", 20], ["UK","B","Q3", 10]]  -- Sample RDD Data

def func(data):
    ldata = list(data)                  # converting iterator class to list
    size = len(ldata)                   # count(*) of the list
    return [i + [size] for i in ldata]  # adding count(*) to the list

sales_count = sales.groupBy( lambda w: (w[0], w[1])).mapValues(func)
# Result: [(('US', 'A'), [['US', 'A', 'Q1', 10, 2], ['US', 'A', 'Q2', 20, 2]]), (('US', 'B'), [['US', 'B', 'Q3', 10, 1]]), (('UK', 'A'), [['UK', 'A', 'Q1', 10, 2], ['UK', 'A', 'Q2', 20, 2]]), (('UK', 'B'), [['UK', 'B', 'Q3', 10, 1]])]

finalResult = sales_count.flatMap(lambda res: res[1])
# Result:  [['US', 'A', 'Q1', 10, 2], ['US', 'A', 'Q2', 20, 2], ['US', 'B', 'Q3', 10, 1], ['UK', 'A', 'Q1', 10, 2], ['UK', 'A', 'Q2', 20, 2], ['UK', 'B', 'Q3', 10, 1]]

# Both the above operations can be combined to one statement
finalResult = sales.groupBy( lambda w: (w[0], w[1])).mapValues(func).flatMap(lambda res: res[1])

注意:像我一样,自定义功能确实很有帮助。您可以轻松地将相同的代码转换为 scala 代码