这个问题是关于聚合操作DataFrame
和RDD
之间的二元性。在Spark SQL中,可以使用表生成UDF进行自定义聚合,但创建其中一个UDF通常明显不如使用RDD可用的聚合函数,特别是如果不需要表输出。
是否有一种有效的方法将{RDD}操作(例如aggregateByKey
)应用于已使用GROUP BY分组或使用ORDERED BY进行排序的DataFrame?
通常,需要一个明确的map
步骤来创建键值元组,例如dataFrame.rdd.map(row => (row.getString(row.fieldIndex("category")), row).aggregateByKey(...)
。这可以避免吗?
答案 0 :(得分:1)
不是真的。虽然DataFrames
可以转换为RDDs
,反之亦然,但这是相对复杂的操作,DataFrame.groupBy
之类的方法与RDD
上的对应方法具有相同的语义。
你可以得到的最接近的东西是Spark 1.6.0中引入的a new DataSet
API。它提供了与DataFrames
和GroupedDataset
类更紧密的集成,并使用自己的一套方法,包括reduce
,cogroup
或mapGroups
:
case class Record(id: Long, key: String, value: Double)
val df = sc.parallelize(Seq(
(1L, "foo", 3.0), (2L, "bar", 5.6),
(3L, "foo", -1.0), (4L, "bar", 10.0)
)).toDF("id", "key", "value")
val ds = df.as[Record]
ds.groupBy($"key").reduce((x, y) => if (x.id < y.id) x else y).show
// +-----+-----------+
// | _1| _2|
// +-----+-----------+
// |[bar]|[2,bar,5.6]|
// |[foo]|[1,foo,3.0]|
// +-----+-----------+
在某些特定情况下,可以使用Orderable
语义来使用structs
或arrays
对数据进行分组和处理。您将在SPARK DataFrame: select the first row of each group