Spark:实现行转列
示例JAVA代码:
import static org.apache.spark.sql.functions.col;
import static org.apache.spark.sql.functions.split;
import static org.apache.spark.sql.functions.explode; import java.util.ArrayList;
import java.util.List; import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession; public class TestSparkSqlSplit {
public static void main(String[] args){
SparkSession sparkSession =SparkSession.builder().appName("test").master("local[*]").getOrCreate();
List<MyEntity> items=new ArrayList<MyEntity>();
MyEntity myEntity=new MyEntity();
myEntity.setId("scene_id1,scene_name1;scene_id2,scene_name2|id1");
myEntity.setName("name");
myEntity.setFields("other");
items.add(myEntity); sparkSession.createDataFrame(items, MyEntity.class).createOrReplaceTempView("test"); Dataset<Row> rows=sparkSession.sql("select * from test");
rows = rows.withColumn("id", explode(split(split(col("id"), "\\|").getItem(), ";"))); rows=rows.withColumn("id1",split(rows.col("id"),",").getItem())
.withColumn("name1",split(rows.col("id"),",").getItem()); rows=rows.withColumn("id",rows.col("id1"))
.withColumn("name",rows.col("name1")); rows=rows.drop("id1","name1"); rows.show(); sparkSession.stop();
}
}
MyEntity.java
import java.io.Serializable; public class MyEntity implements Serializable{
private String id;
private String name;
private String fields;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFields() {
return fields;
}
public void setFields(String fields) {
this.fields = fields;
} }
打印结果:
// :: INFO codegen.CodeGenerator: Code generated in 36.359731 ms
+------+---------+-----------+
|fields| id| name|
+------+---------+-----------+
| other|scene_id1|scene_name1|
| other|scene_id2|scene_name2|
+------+---------+-----------+
Scala实现:
[dx@CDH- ~]$ spark-shell2
-bash: spark-shell2: command not found
[boco@CDH- ~]$ spark2-shell
Setting default log level to "WARN".
...
Spark context available as 'sc' (master = yarn, app id = application_1552012317155_0189).
Spark session available as 'spark'.
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/___/ .__/\_,_/_/ /_/\_\ version 2.2..cloudera1
/_/ 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>
scala> val df = Seq(
| (, "scene_id1,scene_name1;scene_id2,scene_name2",""),
| (, "scene_id1,scene_name1;scene_id2,scene_name2;scene_id3,scene_name3",""),
| (, "scene_id4,scene_name4;scene_id2,scene_name2",""),
| (, "scene_id6,scene_name6;scene_id5,scene_name5","")
| ).toDF("id", "int_id","name");
df: org.apache.spark.sql.DataFrame = [id: int, int_id: string ... more field]
scala> df.show;
+---+--------------------+----+
| id| int_id|name|
+---+--------------------+----+
| |scene_id1,scene_n...| |
| |scene_id1,scene_n...| |
| |scene_id4,scene_n...| |
| |scene_id6,scene_n...| |
+---+--------------------+----+
scala> df.withColumn("int_id", explode(split(col("int_id"), ";")));
res1: org.apache.spark.sql.DataFrame = [id: int, int_id: string ... more field]
scala> res1.show();
+---+--------------------+----+
| id| int_id|name|
+---+--------------------+----+
| |scene_id1,scene_n...| |
| |scene_id2,scene_n...| |
| |scene_id1,scene_n...| |
| |scene_id2,scene_n...| |
| |scene_id3,scene_n...| |
| |scene_id4,scene_n...| |
| |scene_id2,scene_n...| |
| |scene_id6,scene_n...| |
| |scene_id5,scene_n...| |
+---+--------------------+----+
scala> res1.withColumn("int_id", split(col("int_id"), ",")()).withColumn("name", split(col("int_id"), ",")());
res5: org.apache.spark.sql.DataFrame = [id: int, int_id: string ... more field]
scala> res5.show
+---+---------+----+
| id| int_id|name|
+---+---------+----+
| |scene_id1|null|
| |scene_id2|null|
| |scene_id1|null|
| |scene_id2|null|
| |scene_id3|null|
| |scene_id4|null|
| |scene_id2|null|
| |scene_id6|null|
| |scene_id5|null|
+---+---------+----+
scala> res1.withColumn("name", split(col("int_id"), ",")()).withColumn("int_id", split(col("int_id"), ",")());
res7: org.apache.spark.sql.DataFrame = [id: int, int_id: string ... more field]
scala> res7.show
+---+---------+-----------+
| id| int_id| name|
+---+---------+-----------+
| |scene_id1|scene_name1|
| |scene_id2|scene_name2|
| |scene_id1|scene_name1|
| |scene_id2|scene_name2|
| |scene_id3|scene_name3|
| |scene_id4|scene_name4|
| |scene_id2|scene_name2|
| |scene_id6|scene_name6|
| |scene_id5|scene_name5|
+---+---------+-----------+
scala>
int_id(string类型)为null,会自动转化为空字符串,如果filter中写过滤条件col("int_id").notEqual(null),将会过滤掉所有数据:
// MARK:如果int_id(string类型)为null,会自动转化为空字符串,如果filter中写过滤条件col("int_id").notEqual(null),将会过滤掉所有数据。 scala> val df = Seq(
| (1, null,""),
| (2, "-1",""),
| (3, "scene_id4,scene_name4;scene_id2,scene_name2",""),
| (4, "scene_id6,scene_name6;scene_id5,scene_name5","")
| ).toDF("id", "int_id","name");
df: org.apache.spark.sql.DataFrame = [id: int, int_id: string ... 1 more field] scala> df.filter(col("int_id").notEqual(null).and(col("int_id").notEqual("-1")));
res5: org.apache.spark.sql.Dataset[org.apache.spark.sql.Row] = [id: int, int_id: string ... 1 more field] scala> res5.show;
+---+------+----+
| id|int_id|name|
+---+------+----+
+---+------+----+ scala> df.filter(col("int_id").notEqual("").and(col("int_id").notEqual("-1")));
res7: org.apache.spark.sql.Dataset[org.apache.spark.sql.Row] = [id: int, int_id: string ... 1 more field] scala> res7.show;
+---+--------------------+----+
| id| int_id|name|
+---+--------------------+----+
| 3|scene_id4,scene_n...| |
| 4|scene_id6,scene_n...| |
+---+--------------------+----+
int_id如果不包含列传行的条件,数据不会丢失:
scala> scala> val df = Seq(
| (, null,""),
| (, "-1",""),
| (, "scene_id4,scene_name4;scene_id2,scene_name2",""),
| (, "scene_id6,scene_name6;scene_id5,scene_name5","")
| ).toDF("id", "int_id","name");
df: org.apache.spark.sql.DataFrame = [id: int, int_id: string ... more field] scala> scala> df.withColumn("name", split(col("int_id"), ",")()).withColumn("int_id", split(col("int_id"), ",")());
res0: org.apache.spark.sql.DataFrame = [id: int, int_id: string ... more field] scala> res0.show;
+---+---------+--------------------+
| id| int_id| name|
+---+---------+--------------------+
| | null| null|
| | -| null|
| |scene_id4|scene_name4;scene...|
| |scene_id6|scene_name6;scene...|
+---+---------+--------------------+ scala>
Spark:实现行转列的更多相关文章
- spark 累加历史 + 统计全部 + 行转列
spark 累加历史主要用到了窗口函数,而进行全部统计,则需要用到rollup函数 1 应用场景: 1.我们需要统计用户的总使用时长(累加历史) 2.前台展现页面需要对多个维度进行查询,如:产品.地 ...
- Spark基于自定义聚合函数实现【列转行、行转列】
一.分析 Spark提供了非常丰富的算子,可以实现大部分的逻辑处理,例如,要实现行转列,可以用hiveContext中支持的concat_ws(',', collect_set('字段'))实现.但是 ...
- Databricks 第11篇:Spark SQL 查询(行转列、列转行、Lateral View、排序)
本文分享在Azure Databricks中如何实现行转列和列转行. 一,行转列 在分组中,把每个分组中的某一列的数据连接在一起: collect_list:把一个分组中的列合成为数组,数据不去重,格 ...
- SQL Server 动态行转列(参数化表名、分组列、行转列字段、字段值)
一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 实现代码(SQL Codes) 方法一:使用拼接SQL,静态列字段: 方法二:使用拼接SQL, ...
- T-SQL 实现行转列
问题: 我正在寻找一种有效的方式将行转换为SQL服务器中的列 例如,通过下表如何构建出预期结果表. Id Value ColumnName 1 John FirstName 2 2 ...
- Oracle行转列、列转行的Sql语句总结
多行转字符串 这个比较简单,用||或concat函数可以实现 SQL Code 12 select concat(id,username) str from app_userselect i ...
- sql的行转列(PIVOT)与列转行(UNPIVOT)
在做数据统计的时候,行转列,列转行是经常碰到的问题.case when方式太麻烦了,而且可扩展性不强,可以使用 PIVOT,UNPIVOT比较快速实现行转列,列转行,而且可扩展性强 一.行转列 1.测 ...
- 做图表统计你需要掌握SQL Server 行转列和列转行
说在前面 做一个数据统计和分析的项目,每天面对着各种数据,经过存储过程从源表计算汇总后需要写入中间结果表以提高数据使用效率,那么此时就需要用到行转列和列转行. 1.列转行 数据经过计算加工后会直接生成 ...
- SQL SERVER特殊行转列案列一则
今天有个同事找我,他说他有个需求,需要进行行转列,但是又跟一般的行转列有些区别,具体需求如下所说,需要将表1的数据转换为表2的显示格式. 我想了一下,给出了一个解决方法,具体如下所示(先给出测试数据) ...
- SQL Server中使用PIVOT行转列
使用PIVOT行转列 1.建表及插入数据 USE [AdventureDB] GO /****** Object: Table [dbo].[Score] Script Date: 11/25/201 ...
随机推荐
- 怎么用pr(Premiere)给视频添加水印
自己辛辛苦苦剪切的视频,不添加水印,别人肯定会搬走的,作为对视频付出时间的你肯定不想看见这样的事情,下面一起来看看怎么用pr给视频添加水印吧 工具/原料 水印 pr 方法/步骤 首先打 ...
- 微信小程序~wx.getUserInfo逐渐废弃,小程序登录过程将如何优化?
很多的时候我们在做小程序应用的时候,希望用户在使用小程序前进行登录授权,之前登录后通过wx.getUserInfo直接弹出授权的登录方式官方的意思是将不再支持,而是让用户通过下面的方式授权用户信息 & ...
- F 多重背包 判断能否刚好装满
Description 有n种不同大小的数字,每种各个.判断是否可以从这些数字之中选出若干使它们的和恰好为K. Input 首先是一个正整数T(1<=T<=100)接下来是T组数据每组数据 ...
- mydate97时间控件的使用
mydate97官网: http://www.my97.net/dp/index.asp 1:用法如下所示,首先下载一个这个东西: 链接:http://pan.baidu.com/s/1kVmIckv ...
- 渗透测试工具之sqlmap
1. sqlmap是什么 在这个数据有价的时代数据库安全已经成为了重中之重,于是就整理了一下最常用的一款(反正我上大学的时候它还是蛮流行的...)数据库安全方面的渗透测试工具sqlmap的使用笔记. ...
- Springboot实现热部署
所谓的热部署:比如项目的热部署,就是在应用程序在不停止的情况下,实现新的部署 而Springboot在我们每次修改完代码之后,可能只是修改下打印的信息,就得重新启动App类,这样太浪费时间,有没有一种 ...
- 利用sed把一行的文本文件改成每句一行
事实证明,至少在mac-osx上,利用sed插入一个换行符是很难的,常规的命令如: sed 's/[\.\?\!]/\n' file 是不可能的,会把那些标点符号变成n. 尝试了SO上的很多方法 ht ...
- Environment error: “CodeBloks can't find compiler executable in your configured search path's for GNU GCC compiler”
codeblock安装后,提示cant find compiler executable in your configured search paths for GNU GCC Compiler 可能 ...
- x,y
x,y在二维里,横纵坐标容易反,有关处理要小心.
- C++雾中风景番外篇2:Gtest 与 Gmock,聊聊C++的单元测试
正式工作之后,公司对于单元测试要求比较严格.(笔者之前比较懒,一般很少写完整的单测~~).作为一个合格的开发工程师,需要为所编写代码编写适量的单元测试是十分必要的,在实际进行的开发工作之中,TDD(T ...