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,然后按键分组。但由于密钥值远低于值,我认为这会导致性能不佳
答案 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"))
答案 1 :(得分:0)
flatMap不保留组...
因此,如果在groupBy()操作之后对某些内容进行了翻转,则rdd记录将不会被分组