Spark:几种给Dataset增加列的方式、Dataset删除列、Dataset替换null列
几种给Dataset增加列的方式
首先创建一个DF对象:
scala> spark.version
res0: String = 2.2..cloudera1 scala> val df = spark.createDataset(Seq(("key1", , 1.0), ("key1", , 2.0))).toDF("id", "rsrp", "rsrq")
df: org.apache.spark.sql.DataFrame = [id: string, rsrp: int ... more field] scala> df.show
+----+----+----+
| id|rsrp|rsrq|
+----+----+----+
|key1| | 1.0|
|key1| | 2.0|
+----+----+----+ scala> df.printSchema
root
|-- id: string (nullable = true)
|-- rsrp: integer (nullable = false)
|-- rsrq: double (nullable = false)
第一种方式:使用lit()增加常量(固定值)
可以是字符串类型,整型
scala> df.withColumn("sinurl", lit()).show
+----+----+----+------+
| id|rsrp|rsrq|sinurl|
+----+----+----+------+
|key1| | 1.0| |
|key1| | 2.0| |
+----+----+----+------+
scala> df.withColumn("type", lit("mr")).show
+----+----+----+----+
| id|rsrp|rsrq|type|
+----+----+----+----+
|key1| | 1.0| mr|
|key1| | 2.0| mr|
+----+----+----+----+
注意:
lit()是spark自带的函数,需要import org.apache.spark.sql.functions
Since 1.3.0
def lit(literal: Any): Column Creates a Column of literal value. The passed in object is returned directly if it is already a Column. If the object is a Scala Symbol, it is converted into a Column also. Otherwise, a new Column is created to represent the literal value.
第二种方式:使用当前已有的某列的变换新增
scala> df.withColumn("rsrp2", $"rsrp"*).show
+----+----+----+-----+
| id|rsrp|rsrq|rsrp2|
+----+----+----+-----+
|key1| | 1.0| |
|key1| | 2.0| |
+----+----+----+-----+
第三种方式:使用select函数增加列
java方式:
import static org.apache.spark.sql.functions.col;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession;
import org.apache.spark.sql.functions;
import org.apache.spark.sql.api.java.UDF1;
import org.apache.spark.sql.types.DataTypes;
...
private final SimpleDateFormat srcSdf = new SimpleDateFormat("yyyy-MM-dd HH:00:00");
private final SimpleDateFormat destSdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00"); public Dataset<Row> handler(Dataset<Row> esDataset){
UDF1 date_fomat = new UDF1<String, String>() {
private static final long serialVersionUID = 1L; public String call(final String value) throws Exception {
Date date = srcSdf.parse(value);
return destSdf.format(date);
}
};
sparkSession.udf().register("date_fomat_func", date_fomat, DataTypes.StringType); UDF1 to_long = new UDF1<Long, Long>() {
private static final long serialVersionUID = 1L; public Long call(final Long value) throws Exception {
Date date = srcSdf.parse(String.valueOf(value));
return destSdf.parse(destSdf.format(date)).getTime();
}
};
sparkSession.udf().register("to_long_func", to_long, DataTypes.LongType); esDataset=esDataset.withColumn("scan_start_time", functions.callUDF("date_fomat_func", col("scan_start_time")));
esDataset=esDataset.withColumn("scan_stop_time", functions.callUDF("date_fomat_func", col("scan_stop_time")));
esDataset=esDataset.withColumn("timestamp", functions.callUDF("to_long_func", col("timestamp"))); return esDataset;
}
...
scala
scala> import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.DataTypes
scala> df.select(col("*"),
| udf{
| (e:Int) =>
| if(e == "") {
|
| } else {
|
| }
| }.apply(df("rsrp")).cast(DataTypes.DoubleType).as("rsrp_udf")
| ).show
+----+----+----+--------+
| id|rsrp|rsrq|rsrp_udf|
+----+----+----+--------+
|key1| | 1.0| 2.0|
|key1| | 2.0| 2.0|
+----+----+----+--------+
scala> df.select(col("*"),
| when(df("rsrp") > , lit(">10")).when(df("rsrp") === , "=10").otherwise("<10").as("rsrp_compare10")
| ).show
+----+----+----+--------------+
| id|rsrp|rsrq|rsrp_compare10|
+----+----+----+--------------+
|key1| | 1.0| >|
|key1| | 2.0| =|
+----+----+----+--------------+
第四种方式:case when当参数嵌套udf
df.withColumn("r",
when($"rsrp".isNull, lit(null))
.otherwise(udf1($"rsrp"))
.cast(DataTypes.IntegerType)
)
第五种方式:使用expr()函数
scala> df.withColumn("rsrp4", expr("rsrp * 4")).show
+----+----+----+-----+
| id|rsrp|rsrq|rsrp4|
+----+----+----+-----+
|key1| | 1.0| |
|key1| | 2.0| |
+----+----+----+-----+
Dataset删除列
scala> df.drop("rsrp").show
+----+----+
| id|rsrq|
+----+----+
|key1| 1.0|
|key1| 2.0|
+----+----+
scala> df.drop("rsrp","rsrq").show
+----+
| id|
+----+
|key1|
|key1|
+----+
Dataset替换null列
首先,在hadoop目录/user/spark/test.csv
[spark@master ~]$ hadoop fs -text /user/spark/test.csv
key1,key2,key3,key4,key5
aaa,,,t1,
bbb,,,t2,
ccc,,,,
,,,t1,
bbb,,,t3,
,,,t1,
备注:如果想在根目录下执行spark-shell.需要在/etc/profile中追加spark的安装目录:
export SPARK_HOME=/opt/spark-2.2.-bin-hadoop2.
export PATH=$PATH:$SPARK_HOME/bin
使用spark加载.user/spark/test.csv文件
[spark@master ~]$ spark-shell
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
// :: WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Spark context Web UI available at http://192.168.0.120:4040
Spark context available as 'sc' (master = local[*], app id = local-).
Spark session available as 'spark'.
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/___/ .__/\_,_/_/ /_/\_\ version 2.2.
/_/ Using Scala version 2.11. (Java HotSpot(TM) -Bit Server VM, Java 1.8.0_171)
Type in expressions to have them evaluated.
Type :help for more information. scala> val df = spark.read.option("header","true").csv("/user/spark/test.csv")
// :: WARN metastore.ObjectStore: Version information not found in metastore. hive.metastore.schema.verification is not enabled so recording the schema version 1.2.
// :: WARN metastore.ObjectStore: Failed to get database default, returning NoSuchObjectException
// :: WARN metastore.ObjectStore: Failed to get database global_temp, returning NoSuchObjectException
df: org.apache.spark.sql.DataFrame = [key1: string, key2: string ... more fields] scala> df.show
+----+----+----+----+----+
|key1|key2|key3|key4|key5|
+----+----+----+----+----+
| aaa| | | t1| |
| bbb| | | t2| |
| ccc| | |null| |
|null| | | t1|null|
| bbb| | | t3| |
|null| |null| t1| |
+----+----+----+----+----+ scala> df.schema
res3: org.apache.spark.sql.types.StructType = StructType(StructField(key1,StringType,true), StructField(key2,StringType,true),
StructField(key3,StringType,true), StructField(key4,StringType,true), StructField(key5,StringType,true)) scala> df.printSchema
root
|-- key1: string (nullable = true)
|-- key2: string (nullable = true)
|-- key3: string (nullable = true)
|-- key4: string (nullable = true)
|-- key5: string (nullable = true)
一次修改相同类型的多个列的示例。 这里是把key3,key5列中所有的null值替换成1024。 csv导入时默认是string,如果是整型,写法是一样的,有各个类型的重载。
scala> df.na.fill("",Seq("key3","key5")).show
+----+----+----+----+----+
|key1|key2|key3|key4|key5|
+----+----+----+----+----+
| aaa| | | t1| |
| bbb| | | t2| |
| ccc| | |null| |
|null| | | t1||
| bbb| | | t3| |
|null| || t1| |
+----+----+----+----+----+
一次修改不同类型的多个列的示例。 csv导入时默认是string,如果是整型,写法是一样的,有各个类型的重载。
scala> df.na.fill(Map(("key1"->"yyy"),("key3",""),("key4","t88"),("key5",""))).show
+----+----+----+----+----+
|key1|key2|key3|key4|key5|
+----+----+----+----+----+
| aaa| | | t1| |
| bbb| | | t2| |
| ccc| | | t88| |
| yyy| | | t1||
| bbb| | | t3| |
| yyy| || t1| |
+----+----+----+----+----+
不修改,只是过滤掉含有null值的行。 这里是过滤掉key3,key5列中含有null的行
scala> df.na.drop(Seq("key3","key5")).show
+----+----+----+----+----+
|key1|key2|key3|key4|key5|
+----+----+----+----+----+
| aaa| | | t1| |
| bbb| | | t2| |
| ccc| | |null| |
| bbb| | | t3| |
+----+----+----+----+----+
过滤掉指定的若干列中,有效值少于n列的行 这里是过滤掉key1,key2,key3这3列中有效值小于2列的行。最后一行中,这3列有2列都是null,所以被过滤掉了。
scala> df.na.drop(,Seq("key1","key2","key3")).show
+----+----+----+----+----+
|key1|key2|key3|key4|key5|
+----+----+----+----+----+
| aaa| | | t1| |
| bbb| | | t2| |
| ccc| | |null| |
|null| | | t1|null|
| bbb| | | t3| |
+----+----+----+----+----+
同上,如果不指定列名列表,则默认列名列表就是所有列
scala> df.na.drop().show
+----+----+----+----+----+
|key1|key2|key3|key4|key5|
+----+----+----+----+----+
| aaa| | | t1| |
| bbb| | | t2| |
| ccc| | |null| |
| bbb| | | t3| |
+----+----+----+----+----+
参考:
https://blog.csdn.net/coding_hello/article/details/75211995
https://blog.csdn.net/xuejianbest/article/details/81666065
Spark:几种给Dataset增加列的方式、Dataset删除列、Dataset替换null列的更多相关文章
- spark 三种数据集的关系(一)
Catalyst Optimizer: Dataset 数据集仅可用Scala或Java.但是,我们提供了以下上下文来更好地理解Spark 2.0的方向数据集是在2015年作为Apache Spark ...
- Spark获取DataFrame中列的方式--col,$,column,apply
Spark获取DataFrame中列的方式--col,$,column,apply 1.官方说明 2.使用时涉及到的的包 3.Demo 原文作者:大葱拌豆腐 原文地址:Spark获取DataFrame ...
- spark 三种数据集的关系(二)
一个Dataset是一个分布式的数据集,而且它是一个新的接口,这个新的接口是在Spark1.6版本里面才被添加进来的,所以要注意DataFrame是先出来的,然后在1.6版本才出现的Dataset,提 ...
- spark 四种模式
Spark 三种运行模式 一:Spark On Local 此种模式下,我们只需要在安装Spark时不进行hadoop和Yarn的环境配置,只要将Spark包解压即可使用,运行时Spark目 ...
- 一种更高查询性能的列存储方式MaxMinT 第一部分
简介本文描述了一种列存储方式和对应的查询方法,这种存储方式具有更好的查询性能和更小的存储空间. And查询 本文先用直观的图形方式展示and查询时的方式,这也是算法要解决的问题核心.通常在OLAP数据 ...
- Spark两种内存管理
Spark动态内存管理 Spark 1.6 后改为动态内存管理(如果想启用静态内存管理,方法下面会介绍),启动动态主要体现在 存储内存和执行内存的动态.
- 只用css实现“每列四行,加载完一列后数据自动填充到下一列”的效果
只用css实现“每列四行,加载完一列后数据自动填充到下一列”的效果.这个题目用图表示如下: 如果将题目换成“只用css实现每行四列,加载完一行后数据自动填充到下一行”,那这个问题就简单多了,相信大家都 ...
- 在Winform开发中,我们使用的几种下拉列表展示字典数据的方式
在Winform开发中中,我们为了方便客户选择,往往使用系统的字典数据选择,毕竟选择总比输入来的快捷.统一,一般我们都会简单封装一下,以便方便对控件的字典值进行展示处理,本篇随笔介绍DevExpres ...
- 四种常见的 POST 提交数据方式--good
HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS.GET.HEAD.POST.PUT.DELETE.TRACE.CONNECT 这几种.其中 POST 一般用来向服务端提交数据,本文 ...
随机推荐
- python 全栈开发,Day104(DRF用户认证,结算中心,django-redis)
考试第二部分:MySQL数据库 6. MySQL中char和varchar的区别(1分) char是定长,varchar是变长. char的查询速度比varchar要快. 7. MySQL中va ...
- 步步为营-12-Dictionary-翻译
说明:https://pan.baidu.com/s/1nvPqhDJ所需文件在此目录下对应的位置 1 先做一个简单的英汉翻译词典.先搭UI页面 2 将百度网盘中提供的资料放置到bin\debug目录 ...
- Javascript中的函数(三)
一:概述 函数是进行模块化程序设计的基础,编写复杂的Ajax应用程序,必须对函数有更深入的了解.JavaScript中的函数不同于其他的语言,每个函数都是作为一个对象被维护和运行的.通过函数对象的性质 ...
- .NetCore下使用IdentityServer4 & JwtBearer认证授权在CentOS Docker容器中运行遇到的坑及填坑
今天我把WebAPI部署到CentOS Docker容器中运行,发现原有在Windows下允许的JWTBearer配置出现了问题 在Window下我一直使用这个配置,没有问题 services.Add ...
- jsp+servlet实现文件的上传和下载
实现文件的上传和下载首先需要理解几个知识,这样才可以很好的完成文件的上传和下载: (1):上传文件是上传到服务器上,而保存到数据库是文件名 (2):上传文件是以文件转换为二进制流的形式上传的 (3): ...
- java之定时器任务Timer用法
在项目开发中,经常会遇到需要实现一些定时操作的任务,写过很多遍了,然而每次写的时候,总是会对一些细节有所遗忘,后来想想可能是没有总结的缘故,所以今天小编就打算总结一下可能会被遗忘的小点: 1. pub ...
- 6-14 Abbott的复仇 uva816
我的第一题bfs 将方向固定 NESW 然后左转和右转就是+3和+1!!! 还有就是 建立一个数组 储存父节点 这样就可以往回打印出路径 打印的截至条件是 d[][][]==0时 说明到 ...
- 《Android进阶之光》--注解与依赖注入框架
No1: 标准注解: 1)@Override:覆写 2)@Deprecated:过时 3)@SuppressWarnings:取消警告 4)@SafeVarargs:申明使用了可变长度参数的方法 No ...
- UVa140 Bandwidth 【最优性剪枝】
题目链接:https://vjudge.net/contest/210334#problem/F 转载于:https://www.cnblogs.com/luruiyuan/p/5847706.ht ...
- js算法初窥03(搜索及去重算法)
前面我们了解了一些常用的排序算法,那么这篇文章我们来看看搜索算法的一些简单实现,我们先来介绍一个我们在实际工作中一定用到过的搜索算法——顺序搜索. 1.顺序搜索 其实顺序搜索十分简单,我们还是以第一篇 ...