SparkSQL | 行转列与列转行

df = spark.createDataFrame([
    {'id': 1, u'姓名': u'张三', u'分数': 88, u'科目': u'数学'},
    {'id': 2, u'姓名': u'李雷', u'分数': 67, u'科目': u'数学'},
    {'id': 3, u'姓名': u'宫九', u'分数': 77, u'科目': u'数学'},
    {'id': 4, u'姓名': u'王五', u'分数': 65, u'科目': u'数学'},
    {'id': 1, u'姓名': u'张三', u'分数': 77, u'科目': u'英语'},
    {'id': 2, u'姓名': u'李雷', u'分数': 90, u'科目': u'英语'},
    {'id': 3, u'姓名': u'宫九', u'分数': 24, u'科目': u'英语'},
    {'id': 4, u'姓名': u'王五', u'分数': 90, u'科目': u'英语'},
    {'id': 1, u'姓名': u'张三', u'分数': 33, u'科目': u'语文'},
    {'id': 2, u'姓名': u'李雷', u'分数': 87, u'科目': u'语文'},
    {'id': 3, u'姓名': u'宫九', u'分数': 92, u'科目': u'语文'},
    {'id': 4, u'姓名': u'王五', u'分数': 87, u'科目': u'语文'},

])
/usr/lib/spark/python/pyspark/sql/session.py:346: UserWarning: inferring schema from dict is deprecated,please use pyspark.sql.Row instead
  warnings.warn("inferring schema from dict is deprecated,"

行转列

df.createOrReplaceTempView('df')
df.show()
+---+----+----+----+
| id|分数|姓名|科目|
+---+----+----+----+
|  1|  88|张三|数学|
|  2|  67|李雷|数学|
|  3|  77|宫九|数学|
|  4|  65|王五|数学|
|  1|  77|张三|英语|
|  2|  90|李雷|英语|
|  3|  24|宫九|英语|
|  4|  90|王五|英语|
|  1|  33|张三|语文|
|  2|  87|李雷|语文|
|  3|  92|宫九|语文|
|  4|  87|王五|语文|
+---+----+----+----+
# 行转列
df_pivot = spark.sql("""
SELECT
    * 
FROM df
     PIVOT
     (
         SUM(`分数`) 
         FOR `科目` in ('数学','英语','语文')
     )
ORDER BY id      
""").cache()
df_pivot.createOrReplaceTempView('df_pivot')
df_pivot.show()
+---+----+----+----+----+
| id|姓名|数学|英语|语文|
+---+----+----+----+----+
|  1|张三|  88|  77|  33|
|  2|李雷|  67|  90|  87|
|  3|宫九|  77|  24|  92|
|  4|王五|  65|  90|  87|
+---+----+----+----+----+

列转行

spark.sql("""
SELECT
    id
    ,`姓名`
    ,stack(3, '数学', `数学`, '英语', `英语`, '语文', `语文`) as (`科目`, `分数`)
FROM df_pivot
""").cache().show()
+---+----+----+----+
| id|姓名|科目|分数|
+---+----+----+----+
|  1|张三|数学|  88|
|  1|张三|英语|  77|
|  1|张三|语文|  33|
|  2|李雷|数学|  67|
|  2|李雷|英语|  90|
|  2|李雷|语文|  87|
|  3|宫九|数学|  77|
|  3|宫九|英语|  24|
|  3|宫九|语文|  92|
|  4|王五|数学|  65|
|  4|王五|英语|  90|
|  4|王五|语文|  87|
+---+----+----+----+
# 只看转化一部分数据
spark.sql("""
SELECT
    id
    ,`姓名`
    ,stack(1, '数学', `数学`) as (`科目`, `分数`)
FROM df_pivot
""").cache().show()
+---+----+----+----+
| id|姓名|科目|分数|
+---+----+----+----+
|  1|张三|数学|  88|
|  2|李雷|数学|  67|
|  3|宫九|数学|  77|
|  4|王五|数学|  65|
+---+----+----+----+

参考

  • https://databricks.com/blog/2018/11/01/sql-pivot-converting-rows-to-columns.html
  • https://www.cnblogs.com/hhelibeb/p/10310369.html

TODO:

pivot的高级用法, 以及与group by的区别

你可能感兴趣的:(【Spark】)