背景

做过数据清洗ETL工作的都知道,行列转换是一个常见的数据整理需求。在不同的编程语言中有不同的实现方法,比如SQL中使用case+group,或者Power BI的M语言中用拖放组件实现。今天正好需要在pyspark中处理一个数据行列转换,就把这个方法记录下来。

首先明确一下啥叫行列转换,因为这个叫法也不是很统一,有的地方叫转置,有的地方叫透视,不一而足。我们就以下图为例,定义如下:

  • 从左边这种变成右边这种,叫透视(pivot)
  • 反之叫逆透视(unpivot)

Spark实现

构造样本数据

首先我们构造一个以格式保存数据的数据集

from pyspark.sql import SparkSession
spark = SparkSession.builder.appName('JupyterPySpark').enableHiveSupport().getOrCreate() import pyspark.sql.functions as F # 原始数据
df = spark.createDataFrame([('2018-01','项目1',100), ('2018-01','项目2',200), ('2018-01','项目3',300),
('2018-02','项目1',1000), ('2018-02','项目2',2000), ('2018-03','项目x',999)
], ['年月','项目','收入'])

样本数据如下,我们可以看到,每一个项目在指定月份都只有一行记录,并且项目是稀疏的。即,不是每个项目都会出现在每一个月份中,如项目2仅出现在2018-01当中。

+-------+---+----+
| 年月| 项目| 收入|
+-------+---+----+
|2018-01|项目1| 100|
|2018-01|项目2| 200|
|2018-01|项目3| 300|
|2018-02|项目1|1000|
|2018-02|项目2|2000|
|2018-03|项目x| 999|
+-------+---+----+

透视Pivot

透视操作简单直接,逻辑如下

  • 按照不需要转换的字段分组,本例中是年月
  • 使用pivot函数进行透视,透视过程中可以提供第二个参数来明确指定使用哪些数据项;
  • 汇总数字字段,本例中是收入

代码如下

df_pivot = df.groupBy('年月')\
.pivot('项目', ['项目1','项目2','项目3','项目x'])\
.agg(F.sum('收入'))\
.fillna(0)

结果如下

+-------+----+----+---+---+
| 年月| 项目1| 项目2|项目3|项目x|
+-------+----+----+---+---+
|2018-03| 0| 0| 0|999|
|2018-02|1000|2000| 0| 0|
|2018-01| 100| 200|300| 0|
+-------+----+----+---+---+

逆透视Unpivot

Spark没有提供内置函数来实现unpivot操作,不过我们可以使用Spark SQL提供的stack函数来间接实现需求。有几点需要特别注意:

  • 使用selectExpr在Spark中执行SQL片段;
  • 如果字段名称有中文,要使用反引号**`** 把字段包起来;

代码如下

df_pivot.selectExpr("`年月`",
"stack(4, '项目1', `项目1`,'项目2', `项目2`, '项目3', `项目3`, '项目x', `项目x`) as (`项目`,`收入`)")\
.filter("`收入` > 0 ")\
.orderBy(["`年月`", "`项目`"])\
.show()

结果如下

+-------+---+----+
| 年月| 项目| 收入|
+-------+---+----+
|2018-01|项目1| 100|
|2018-01|项目2| 200|
|2018-01|项目3| 300|
|2018-02|项目1|1000|
|2018-02|项目2|2000|
|2018-03|项目x| 999|
+-------+---+----+


Reference:

https://juejin.im/post/5b1e343f518825137c1c6a27  掘金

【转】Spark实现行列转换pivot和unpivot的更多相关文章

  1. 通过sql做数据透视表,数据库表行列转换(pivot和Unpivot用法)(一)

    在mssql中大家都知道可以使用pivot来统计数据,实现像excel的透视表功能 一.MSsqlserver中我们通常的用法 1.Sqlserver数据库测试 ---创建测试表 Create tab ...

  2. sql行列转换PIVOT与unPIVOT

    基本语法 select * from Mould pivot ( count(ID)for ProductTypeCode in ( [FC], [RCU], [RCD] )) as PVT; wit ...

  3. SQL Fundamentals: 子查询 || 行列转换(PIVOT,UNPIVOT,DECODE),设置数据层次(LEVEL...CONNECT BY)

    SQL Fundamentals || Oracle SQL语言 子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5 ...

  4. SQL Server中行列转换 Pivot UnPivot

    SQL Server中行列转换 Pivot UnPivot PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PI ...

  5. SQL Server中行列转换 Pivot UnPivot

    PIVOT用于将列值旋转为列名(即行转列),在SQLServer 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PIVOT(聚合函数(列)FOR 列 in (-) )AS P 完 ...

  6. SQLServer中行列转换Pivot UnPivot

    PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P ...

  7. 多列的行列转换(PIVOT,UNPIVOT)

    形式1 形式2 形式3 有时候可能会有这样的需求: 将一张表的所有列名转做为数据的一列数据,将一列数据作为整张表的列名 当列比较多时,只用PIVOT是解决不了的,经过研究,需要将UNPIVOT 和 P ...

  8. SQL中行列转换Pivot

    --建表 ),课程 ),分数 int) --插入数据 ) ) ) ) ) ) 1.静态行转列(确定有哪些列) select 姓名, end)语文, end)数学, end)物理 from tb gro ...

  9. 行列转换 pivot

    select * from ( select isnull(c.type,'其他') type,d from ( select ID,Record_code,code,day(thedate) d f ...

随机推荐

  1. Kotlin入门学习笔记

    前言 本文适合人群 有一定的java基础 变量与方法 变量声明及赋值 var 变量名: 变量类型 val 变量名: 变量类型 这里,var表示可以改变的变量,val则是不可改变的变量(第一个赋值之后, ...

  2. Android项目刮刮奖详解(四)

    Android项目刮刮奖详解(三) 前言 上一期我们已经是完成了刮刮卡的基本功能,本期就是给我们的项目增加个功能以及美化一番 目标 增加功能 用户刮卡刮到一定程度的时候,清除遮盖层 在遮盖层放张图片, ...

  3. 收集的博客网址springboot、cloud

    纯洁的微笑(spring-boot,cloud等)

  4. linux学习笔记-shell-script相关知识

    我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! 一.shell script的执行方法 条件:shell脚本文件必须具备可读可执行权限 1.直接命令执行 (1)使用绝对路径执行 ...

  5. 转载:Linux服务器Cache占用过多内存导致系统内存不足最终java应用程序崩溃解决方案

    原文链接: https://blog.csdn.net/u014740338/article/details/66975550 问题描述 Linux内存使用量超过阈值,使得Java应用程序无可用内存, ...

  6. Vsphere 回收未消使用的磁盘空间

    下载sdelete.exe 执行 sdelete.exe -z E: ,然后又恢复为原可用空间 关机   SHH进入物理主机,找到对应的虚机文件 执行vmkfstools -K test-Win200 ...

  7. Andriod Studio安装教程

    最近开设安卓课程,无奈于开发团队不再更新eclipse上sdk兼容问题,在eclipse上浪费了两天时间,换了Andriod Studio, Andriod Studio下载网址:http://www ...

  8. Dagger2源码浅析

    dagger2是目前android端比较火的一款依赖注入框架,先来看下基本的用法吧: 首先提供module,类似于工厂: @Module public class ApiServiceModule { ...

  9. TomCat的安装及测试

    1.每个版本的安装都是一样,解压之后是一个文件夹 2.配置环境变量,右击我的电脑,属性--高级属性设置--环境变量--新建--配path即可(path后加;%CATALINA_HOME%\bin;) ...

  10. rpc接口调用以太坊智能合约

    rpc接口调用以太坊智能合约 传送门: 柏链项目学院   在以太坊摸爬滚打有些日子了,也遇到了各种各样的问题.这几天主要研究了一下如何通过rpc接口编译.部署和调用合约.也遇到了一些困难和问题,下面将 ...