经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » Spark » 查看文章
Spark SQL中列转行(UNPIVOT)的两种方法
来源:cnblogs  作者:氢氦  时间:2019/1/24 9:35:33  对本文有异议

行列之间的互相转换是ETL中的常见需求,在Spark SQL中,行转列有内建的PIVOT函数可用,没什么特别之处。而列转行要稍微麻烦点。本文整理了2种可行的列转行方法,供参考。

 

本文链接:https://www.cnblogs.com/hhelibeb/p/10310369.html

测试数据准备

本文的环境是Windows 10, Spark 2.4,开发语言是Python。首先构建一点初始测试数据,

  1. from pyspark.sql import SparkSession
  2. spark = SparkSession.builder.appName('TestAPP').enableHiveSupport().getOrCreate()
  3. df = spark.createDataFrame([('数学','张三',88), ('语文','张三',92), ('英语','张三',77),
  4. ('数学','王五',65), ('语文','王五',87), ('英语','王五',90),
  5. ('数学','李雷',67), ('语文','李雷',33), ('英语','李雷',24),
  6. ('数学','宫九',77), ('语文','宫九',87), ('英语','宫九',90)
  7. ], ['科目','姓名','分数']).orderBy('科目')
  8. df.show()

执行程序,可以看到数据如下,

  1. +----+----+----+
  2. |科目|姓名|分数|
  3. +----+----+----+
  4. |数学|张三| 88|
  5. |数学|李雷| 67|
  6. |数学|宫九| 77|
  7. |数学|王五| 65|
  8. |英语|张三| 77|
  9. |英语|宫九| 90|
  10. |英语|李雷| 24|
  11. |英语|王五| 90|
  12. |语文|李雷| 33|
  13. |语文|宫九| 87|
  14. |语文|张三| 92|
  15. |语文|王五| 87|
  16. +----+----+----+

行转列

如上述,使用PIVOT函数即可实现行转列,

  1. df.createOrReplaceTempView('scores')
  2. sql_content = '''select * from scores
  3. pivot
  4. (
  5. sum(`分数`) for
  6. `姓名` in ('张三','王五','李雷','宫九')
  7. )
  8. '''
  9. df_pivot = spark.sql(sql_content)
  1. df_pivot.show()

 得到结果,

  1. +----+----+----+----+----+
  2. |科目|张三|王五|李雷|宫九|
  3. +----+----+----+----+----+
  4. |数学| 88| 65| 67| 77|
  5. |英语| 77| 90| 24| 90|
  6. |语文| 92| 87| 33| 87|
  7. +----+----+----+----+----+

列转行

本文整理的两种办法是使用Spark中的stack函数lateral view + explode函数

stack()

stack(n, expr1, ..., exprk) - 会将expr1, ..., exprk 分割为n行.

  1. df_pivot.createOrReplaceTempView('v_pivot')
  2. sql_content = '''select `科目`,
  3. stack(4, '张三', `张三`, '王五', `王五`, '李雷', `李雷`, '宫九', `宫九`) as (`姓名`, `分数` )
  4. from v_pivot
  5. '''
  6. df_unpivot1 = spark.sql(sql_content)
  7. df_unpivot1.show()

可以看到,结果的结构和初始数据的结构相同,

  1. +----+----+----+
  2. |科目|姓名|分数|
  3. +----+----+----+
  4. |数学|张三| 88|
  5. |数学|王五| 65|
  6. |数学|李雷| 67|
  7. |数学|宫九| 77|
  8. |英语|张三| 77|
  9. |英语|王五| 90|
  10. |英语|李雷| 24|
  11. |英语|宫九| 90|
  12. |语文|张三| 92|
  13. |语文|王五| 87|
  14. |语文|李雷| 33|
  15. |语文|宫九| 87|
  16. +----+----+----+

 

lateral view + explode()

explode函数可以把数组分割为多行,比如,

  1. > SELECT explode(array(10, 20));
  2. 10
  3. 20

lateral view使用表生成函数将每个输入行转换为0或多个输出行。最常见的用法是和explode函数一起使用。

  1. sql_content = '''select `科目`, split(temp1, ':')[0] as `姓名`, split(temp1, ':')[1] as `分数`
  2. from(
  3. select `科目`, concat(
  4. '张三:', `张三`, ',',
  5. '王五:', `王五`, ',',
  6. '李雷:', `李雷`, ',',
  7. '宫九:', `宫九`
  8. ) temp
  9. from v_pivot
  10. ) lateral view explode(split(temp, ',')) as temp1
  11. '''
  12. df_unpivot2 = spark.sql(sql_content)
  13. df_unpivot2.show()

结果同上,

  1. +----+----+----+
  2. |科目|姓名|分数|
  3. +----+----+----+
  4. |数学|张三| 88|
  5. |数学|王五| 65|
  6. |数学|李雷| 67|
  7. |数学|宫九| 77|
  8. |英语|张三| 77|
  9. |英语|王五| 90|
  10. |英语|李雷| 24|
  11. |英语|宫九| 90|
  12. |语文|张三| 92|
  13. |语文|王五| 87|
  14. |语文|李雷| 33|
  15. |语文|宫九| 87|
  16. +----+----+----+

 

参考链接:Spark SQL, Built-in Functions

Spark实现行列转换pivot和unpivot

hive lateral view 与 explode详解

SQL Guide

 

原文链接:http://www.cnblogs.com/hhelibeb/p/10310369.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号