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 一般用来向服务端提交数据,本文 ...
随机推荐
- Redis五大数据类型以及操作
目录: 一.redis的两种链接方式 二.redis的字符串操作(string) 三.redis的列表操作(list) 四.redis的散列表操作(类似于字典里面嵌套字典) 五.redis的集合操作( ...
- PHP将数据写入指定文件中
首先创建一个空的txt文件,这里我们创建了一个1.txt的空文件. 第一种方法:fwrite函数 <?php $file=fopen('1.txt','rb+'); var_dump(fwrit ...
- hdu3308
区间合并比较模板的题,就是求一个区间的LCIS 线段树维护左最大LCIS,右最大LCIS,区间LCIS 看代码就行 #include<iostream> #include<cstri ...
- cf276E 两棵线段树分别维护dfs序和bfs序,好题回头再做
搞了一晚上,错了,以后回头再来看 /* 对于每次更新,先处理其儿子方向,再处理其父亲方向 处理父亲方向时无法达到根,那么直接更新 如果能达到根,那么到兄弟链中去更新,使用bfs序 最后,查询结点v的结 ...
- 微信公众号开发JS-SDK(1.2)
概述 微信js-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包. 通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照.选图.语音.位置等手机系统的能力,同时可以直接使用微 ...
- 【C++ Primer | 15】C++类内存分布
C++类内存分布 书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看编译器是怎么处理类成员内存分布的,特别是在继承.虚函数存在的情况下. 下面可以定义一个类,像下面这样: c ...
- HDU1285 确定名次 拓扑排序
Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委 ...
- 【Java】 剑指offer(41) 数据流中的中位数
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中 ...
- 091实战 Nginx配置(日志服务器中关于日志的产生)
一:概括 1.需要配置的概括 定义日志格式 日志的分割字段:^A 日志格式:IP地址^A服务器时间^A请求参数 配置location,记录请求日志到本地磁盘 将数据按照给定的日志格式存储到本地磁盘 二 ...
- Python6 - 函数总结
一.函数的基本知识 定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可 特性: 减少重复代码 使程序变的可扩展 使程序变得易维护 1.1函数定义规则 ...