DataSet(DataFrame)的基本操作
有类型操作
转换
flatMap
通过 flatMap
可以将一条数据转为一个数组, 后再展开这个数组放入 Dataset
import spark.implicits._
val ds = Seq("hello world", "hello spark").toDS()
ds.flatMap( _.split(" ") ).show()
map
map
可以将数据集中每条数据转为另一种形式
import spark.implicits._
val ds = Seq(Person("zhangsan", 15), Person("lisi", 15)).toDS()
ds.map( person => Person(person.name, person.age * 2) ).show()
mapPartitions
mapPartitions
和 map
一样, 但是 map
的处理单位是每条数据, mapPartitions
的处理单位是每个分区
import spark.implicits._
val ds = Seq(Person("zhangsan", 15), Person("lisi", 15)).toDS()
ds.mapPartitions( iter => {
val returnValue = iter.map(
item => Person(item.name, item.age * 2)
)
returnValue
} )
.show()
transform
map
和 mapPartitions
以及 transform
都是转换, map
和 mapPartitions
是针对数据, 而 transform
是针对整个数据集, 这种方式最大的区别就是 transform
可以直接拿到 Dataset
进行操作
import spark.implicits._
val ds = spark.range(5)
ds.transform( dataset => dataset.withColumn("doubled", 'id * 2) )
as
as[Type]
算子的主要作用是将弱类型的 Dataset
转为强类型的 Dataset
, 它有很多适用场景, 但是最常见的还是在读取数据的时候, 因为 DataFrameReader
体系大部分情况下是将读出来的数据转换为 DataFrame
的形式, 如果后续需要使用 Dataset
的强类型 API
, 则需要将 DataFrame
转为 Dataset
. 可以使用 as[Type]
算子完成这种操作
import spark.implicits._
val structType = StructType(
Seq(
StructField("name", StringType),
StructField("age", IntegerType),
StructField("gpa", FloatType)
)
)
val sourceDF = spark.read
.schema(structType)
.option("delimiter", "\t")
.csv("dataset/studenttab10k")
val dataset = sourceDF.as[Student] //student为定义的样例类
dataset.show()
过滤
filter
filter
用来按照条件过滤数据集
import spark.implicits._
val ds = Seq(Person("zhangsan", 15), Person("lisi", 15)).toDS()
ds.filter( person => person.name == "lisi" ).show()
聚合
groupByKey
grouByKey
算子的返回结果是 KeyValueGroupedDataset
, 而不是一个 Dataset
, 所以必须要先经过 KeyValueGroupedDataset
中的方法进行聚合, 再转回 Dataset
, 才能使用 Action
得出结果
其实这也印证了分组后必须聚合的道理
import spark.implicits._
val ds = Seq(Person("zhangsan", 15), Person("zhangsan", 15), Person("lisi", 15)).toDS()
ds.groupByKey( person => person.name ).count().show()
切分
randomSplit
randomSplit
会按照传入的权重随机将一个 Dataset
分为多个 Dataset
, 传入 randomSplit
的数组有多少个权重, 最终就会生成多少个 Dataset
, 这些权重的加倍和应该为 1, 否则将被标准化
val ds = spark.range(15)
val datasets: Array[Dataset[lang.Long]] = ds.randomSplit(Array[Double](2, 3))
datasets.foreach(dataset => dataset.show())
sample
sample
会随机在 Dataset
中抽样
val ds = spark.range(15)
ds.