Spark--透視函數(shù)pivot應(yīng)用(行列轉(zhuǎn)換)

應(yīng)用背景

歡迎各位訪問鏈接中原創(chuàng)博客
Spark中行列轉(zhuǎn)換,即數(shù)據(jù)的透視。



以上圖為例,進(jìn)行如下定義:

  • 從左邊這種變成右邊這種,叫透視(pivot)
  • 反之叫逆透視(unpivot)

Spark實現(xiàn)

python、scala、java均可以進(jìn)行實現(xiàn)

構(gòu)造樣本數(shù)據(jù)

from pyspark.sql import SparkSession
spark = SparkSession.builder.appName('JupyterPySpark').enableHiveSupport().getOrCreate()
import pyspark.sql.functions as F
# 原始數(shù)據(jù) 
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)
                           ], ['年月','項目','收入'])

對spark dataframe進(jìn)行show格式查看

 df.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|
        +-------+---+----+
    '''

透視pivot

透視操作簡單直接,邏輯如下

  • 按照不需要轉(zhuǎn)換的字段分組,本例中是年月;
  • 使用pivot函數(shù)進(jìn)行透視,透視過程中可以提供第二個參數(shù)來明確指定使用哪些數(shù)據(jù)項,(可以指定不再DataFrame中schema的字段);
  • 匯總數(shù)字字段,本例中是收入;
  • pivot 只能跟在groupby之后
    具體代碼如下:
df_pivot = df.groupBy('年月') \
        .pivot('項目', ['項目1', '項目2', '項目3', '項目x', 'weizhi']) \
        .agg(F.sum('收入')) \
        .fillna(0)
    print("============df_pivot===================")
    df_pivot.show()
    '''
    +-------+----+----+---+---+------+
    |     年月| 項目1| 項目2|項目3|項目x|weizhi|
    +-------+----+----+---+---+------+
    |2018-03|   0|   0|  0|999|     0|
    |2018-02|1000|2000|  0|  0|     0|
    |2018-01| 100| 200|300|  0|     0|
    +-------+----+----+---+---+------+
    '''

逆透視Unpivot

  • Spark沒有提供內(nèi)置函數(shù)來實現(xiàn)unpivot操作,不過我們可以使用Spark SQL提供的stack函數(shù)來間接實現(xiàn)需求。有幾點(diǎn)需要特別注意:
    • 使用selectExpr在Spark中執(zhí)行SQL片段;
    • 如果字段名稱有中文,要使用反引號` 把字段包起來;
      具體代碼如下:
 # 逆透視Unpivot
unpivot_df =  df_pivot.selectExpr("`年月`",
                        "stack(4, '項目1', `項目1`,'項目2', `項目2`, '項目3', `項目3`, '項目x', `項目x`) as (`項目`,`收入`)") \
        .filter("`收入` > 0 ") \
        .orderBy(["`年月`", "`項目`"]) \
unpivot_df.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|
+-------+---+----+
'''

這個函數(shù)功能在實際的開發(fā)過程中還是很需要進(jìn)行使用的,練習(xí)一下。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容