在RDD中展平嵌套元组

时间:2018-05-30 18:42:22

标签: sql scala apache-spark rdd flatten

我正在使用Spark SQL从表中提取行。其中一些数据反复出现,我正在尝试计算出现次数。本质上,我正在尝试执行基本的“字数统计”示例,但我的数据不是(Word : String, Count : Int)形式,而是有一行数据替换字/字符串。

更具体地说,我的数据看起来像:RDD[((row), count)],其中row是从sql表中提取的,包含字符串,双精度,整数等。

它是RDD形式,因为我想使用reduceByKey。见:Avoid groupByKey。它是一个(Key, Value)对,带有一个很长的密钥(来自sql数据库的某一行),它的值是“字数”。

我的应用正在执行此操作:

myDataframe
    // Append a 1 to each row
    .map(row => (row, 1))
    // Convert to RDD so we can use the reduceByKey method
    .rdd
    // Add up the 1's corresponding to matching keys
    .reduceByKey(_ + _)
    //Filter by rows that show up more than 10 times
    .filter(_._2 > 100)

    ...

现在假设我的行数据包含(string, double, int)。 这是我想将数据从RDD[((string, double, int), count)]解压缩到RDD[(string, double, int, count)]的地方,这样我最终可以将这些数据保存到另一个SQL表中。

是否有一些方法允许我解压缩这个...嵌套元组的内容......有点像?

我的解决方案是“解压缩”RDD的元素,如下所示: .map(row => (row._1._1, row._1._2, row._1._3, row._2))

但必须有更好的方法!如果我决定从行中获取更多元素,我必须修改此.map()调用。

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以使用Row的{​​{1}}和toSeq,如下例所示:

fromSeq

答案 1 :(得分:1)

您不必恢复使用RDD;您正确引用的文章警告使用RDD.groupByKey,但不应该应用于DataFrame的groupBy 。在DataFrame上使用groupBy是安全的(并且高效)!查看更多here

因此,要按所有的DataFrame列进行分组,请计算每个组的出现次数,并过滤计数为>的组。 10,你可以简单地使用:

df.groupBy(df.columns.map(col): _*) // alternatively: df.groupBy(df.columns.head, df.columns.tail: _*)
  .count()
  .filter($"count" > 10)

结果的架构类似于输入,附加count长列。