Spark中的FlatMap和GroupBy

时间:2016-11-09 15:02:52

标签: apache-spark pyspark

A有一些看起来像这样的数据

from local_spark import sc,sqlContext
rdd = sc.parallelize([
                        ("key1", 'starttime=10/01/2015', 'param1', '1,2,3,99,88'), 
                        ("key2", 'starttime=10/02/2015'', 'param1', '11,12'), 
                        ("key1", 'starttime=10/01/2015'', 'param2', '66,77')
                    ])

第三个参数是逗号分隔的(每秒一个值)值列表,可能非常大

我需要做的是按键对数据集进行分组,然后使用flapMap对其进行分组。 预期结果将是这样的:

(key1)     # rdd key

# for each key, a table with the values
key   timestamp     param1   param2
key1   10/01/2015    1         66     
key1   10/01/2015    2         77
key1   10/01/2015    3         null
key1   10/01/2015    99        null


(key2)    # rdd key
key   timestamp     param1   param2
key2   10/01/2015    11       null     
key2   10/01/2015    12       null

到目前为止,我试图做的是这样的: rdd.groupByKey()。flatMap(functionToParseValuesAndTimeStamps)

如果我做这样的事情,flatMap操作的结果是否仍然按键分组?我是否会通过"操作

obs:一个更天真的方法是先将flapMap,然后按键分组。但由于密钥值远低于值,我认为这会导致性能不佳

2 个答案:

答案 0 :(得分:0)

我建议转换为数据框并编写UDF以拆分列,经过一些争论后,您可以按照此代码took进行操作,并根据您的数据进行编辑。复制并粘贴Spark-Shell以使用它。

import org.apache.spark.{ SparkConf, SparkContext }
import org.apache.spark.sql.types._
import org.apache.spark.sql._
import org.apache.spark.sql.functions._

val sqlContext = new org.apache.spark.sql.SQLContext(sc)

import sqlContext.implicits._
import org.apache.spark.sql.functions.udf

val df2 = Seq( ("key1", "11", "12"),
               ("key2", "66", "77")).toDF("keys", "num1", "num2")


def toLong(df: DataFrame, by: Seq[String]): DataFrame = {
                 val (cols, types) = df.dtypes.filter{ case (c, _) => !by.contains(c)}.unzip
                 require(types.distinct.size == 1)

                 val kvs = explode(array(
                   cols.map(c => struct(lit(c).alias("key"), col(c).alias("val"))): _*
                 ))

                 val byExprs = by.map(col(_))

                 df2
                   .select(byExprs :+ kvs.alias("_kvs"): _*)
                   .select(byExprs ++ Seq($"_kvs.key", $"_kvs.val"): _*)
               }

val x = toLong(df2, Seq("keys"))

继承人看起来如何 enter image description here

答案 1 :(得分:0)

flatMap不保留组...

因此,如果在groupBy()操作之后对某些内容进行了翻转,则rdd记录将不会被分组