一、http://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.sql.Dataset
二、个论
1. describe
Computes basic statistics for numeric and string columns, including count, mean, stddev, min, and max.
2.first=head()=head(1) 取第一行,不是第一列,返回ROW类型
Returns the first row.
3.get(num) 根据列序号取值
4.select
- select传入字符串类型的列名时,只能传入列名,不能传入列的计算表达式,比如
colA + 1
,如果想传入sql语句,用seleExpr。 def select(col: String, cols: String*): DataFrame
这个方法的意义是表示至少要传入1个参数。如果传入的是Column,则可以直接传入参数序列。
注意:不能直接像java那样用数组匹配可变参数,要在集合后面加:_*
才行,否则spark会把整个集合当成列名。- 如果是用Column类型的集合,就可以直接传入一个参数序列。此处不知为何这样设计???
val targetFields = evaluator.getTargetFields.toList.map(_.getFieldName.toString)
val outputFields = evaluator.getOutputFields.toList.map(_.getFieldName.toString)
//这里必须2个参数,args0必须单独设1个列名,不知为何???
val resultDF: DataFrame = transformer.transform(df).select(colmnName,targetFields ++ outputFields : _ *)
val targetFields1 = evaluator.getTargetFields.toList.map(old => col(old.getFieldName.toString))
val outputFields1 = evaluator.getOutputFields.toList.map(old => col(old.getFieldName.toString))
//如果是Column类型的重载,就可以直接传入参数序列
val resultDF1: DataFrame = transformer.transform(df).select(col(colmnName) +: targetFields1 ::: outputFields1 : _ *)
5. withColumn
给当前df增加一列,或者用一个Column对象替换一个已存在的列,
/**
* Returns a new Dataset by adding a column or replacing the existing column that has
* the same name.
*
* @group untypedrel
* @since 2.0.0
*/
def withColumn(colName: String, col: Column): DataFrame = {
val resolver = sparkSession.sessionState.analyzer.resolver
val output = queryExecution.analyzed.output
val shouldReplace = output.exists(f => resolver(f.name, colName))
if (shouldReplace) {
val columns = output.map { field =>
if (resolver(field.name, colName)) {
col.as(colName)
} else {
Column(field)
}
}
select(columns : _*)
} else {
select(Column("*"), col.as(colName))
}
}
从源码中可以看出,如果是替换,最后会调用select所有列,如果是增加,会调用select(原来的所有列 + 增加的列) ==》 select(Column(*),col.as(colName))。
col.as(colName)的意思是创建一个clumn对象,别名是colName。
注意:dsl风格时,UDF的入参和出参都是Column对象
6. text和textFile
sparkSession可以直接通过txt文本来创建df,可以直接读取没有schema的text文件,通过sparkSession.read.text(),但获取的df把一行全放到一列中且名字默认为value。官方文档还说后面会有分区列,暂时没弄明白。
text是返回df,textFile是返回DataSet[String]
![](https://i-blog.csdnimg.cn/blog_migrate/9917ccb356eaf610e3cf267cde487adc.png)
![](https://i-blog.csdnimg.cn/blog_migrate/8685e018944d6de7555a1a477ab24612.png)
其实底层使用的hdfs的TextInputFormat,但TextInputFormat读进来返回的是kv,偏移量 -> 值,但textFile把k给去掉了
6. schema(treeString、fields)、printSchema()
df对应结构数据化的结构==》必须带表结构,用StructType对象封装。
![](https://i-blog.csdnimg.cn/blog_migrate/cd72b4c79777fc0277c976a9880a006b.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b5f391c1f471c6eab6822177661427b2.png)
schema返回df的schema,
schema对象的treeString然后打印相当于df的printSchema()
schema对象的fields返回StructType的所有StructFiled对象