在Spark中實(shí)現(xiàn)Pandas melt函數(shù)

本文首發(fā)于在Spark中實(shí)現(xiàn)Pandas melt函數(shù) | 磚瓦匠杜重
轉(zhuǎn)載需注明出處。


最近在做一個(gè)用Spark洗數(shù)據(jù)的工作,其中的一個(gè)步驟需要將寬數(shù)據(jù)轉(zhuǎn)換為長數(shù)據(jù)毒返,發(fā)現(xiàn)Spark里面并沒有原生的方法實(shí)現(xiàn)這樣的效果引有,后面發(fā)現(xiàn)可以利用explode方法栖秕,間接實(shí)現(xiàn)這樣數(shù)據(jù)的轉(zhuǎn)換嫩与,本文介紹整個(gè)思路玫鸟。

[圖片上傳失敗...(image-2d063a-1629296267664)]


explode 方法可以將DataFrame一行中ArrayType或者StructType的集合數(shù)據(jù)下每一項(xiàng)导绷,提取出來單獨(dú)作為新DataFrame的一行中的一項(xiàng),實(shí)現(xiàn)從一個(gè)集合到多個(gè)個(gè)體的轉(zhuǎn)換屎飘,一行到多行的轉(zhuǎn)換妥曲。具體實(shí)現(xiàn)效果如下:

[圖片上傳失敗...(image-98c126-1629296267664)]

回到在Spark中實(shí)現(xiàn)melt方法,我們可以首先將需要melt的列合并ArrayType的集合钦购,集合中的每個(gè)元素以(variable_name, variable_value)的StructType呈現(xiàn)檐盟,再利用explode 方法進(jìn)行一到多的拓展,最后再將(variable_name, variable_value)分成兩列即可押桃,示意圖如下:

[圖片上傳失敗...(image-c7af-1629296267664)]

我將最后代碼整理如下葵萎,函數(shù)采用了和Pandas中類似的參數(shù)命名方式:

def sparkMelt(frame, id_vars=None, value_vars=None, var_name=None, value_name=None):
    """
    Pandas melting functions implemented in Spark

    Args:
        frame (Spark DataFrame): Spark dataframe to work on.
        id_vars (list, optional): Column(s) to use as identifier variables. Defaults to None.
        value_vars (list, optional): Column(s) to unpivot. If not specified, uses all columns that are not set as id_vars. Defaults to None.
        var_name (list, optional): Name to use for the ‘variable’ column. Defaults to None. If None, use 'variable'.
        value_name (list, optional): Name to use for the ‘value’ column. Defaults to None. If None, use 'value'.

    Returns:
        [Spark DataFrame]: Unpivoted Spark DataFrame.
    """
    
    id_vars = id_vars if not id_vars else frame.columns

    value_vars = [col_name for col_name in frame.columns if col_name not in id_vars] \
        if not value_vars else value_vars
    
    # if value_vars is None, no columns need to be melted
    if not value_vars:
        return frame
    
    var_name = 'variable' if not var_name else var_name
    value_name = 'value' if not value_name else value_name

    col_lst = ['height', 'weight']

    for col_name in col_lst:
        frame = frame.withColumn(col_name,
                                 F.struct(F.lit(col_name).alias('var_name'), F.col(col_name).alias('var_value')))

    frame = frame.withColumn('_zip', F.array(*col_lst)) \
        .withColumn('_key_value', F.explode('_zip')) \
        .withColumn(var_name,  F.col('_key_value')['var_name']) \
        .withColumn(value_name,  F.col('_key_value')['var_value'])

    df_col = [col_name for col_name in frame.columns if col_name not in (
        *col_lst, '_zip', '_key_value')]
    frame = frame.select(*df_col)

    return frame
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市唱凯,隨后出現(xiàn)的幾起案子羡忘,更是在濱河造成了極大的恐慌,老刑警劉巖磕昼,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卷雕,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡票从,警方通過查閱死者的電腦和手機(jī)漫雕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來峰鄙,“玉大人浸间,你說我怎么就攤上這事∫髁瘢” “怎么了魁蒜?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長吩翻。 經(jīng)常有香客問我兜看,道長,這世上最難降的妖魔是什么仿野? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮她君,結(jié)果婚禮上脚作,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好球涛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布劣针。 她就那樣靜靜地躺著,像睡著了一般亿扁。 火紅的嫁衣襯著肌膚如雪捺典。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天从祝,我揣著相機(jī)與錄音襟己,去河邊找鬼。 笑死牍陌,一個(gè)胖子當(dāng)著我的面吹牛擎浴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播毒涧,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼贮预,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了契讲?” 一聲冷哼從身側(cè)響起仿吞,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎捡偏,沒想到半個(gè)月后唤冈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡霹琼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年务傲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枣申。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡售葡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出忠藤,到底是詐尸還是另有隱情挟伙,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布模孩,位于F島的核電站尖阔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏榨咐。R本人自食惡果不足惜介却,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望块茁。 院中可真熱鬧齿坷,春花似錦桂肌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至遂蛀,卻和暖如春谭跨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背李滴。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來泰國打工螃宙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人悬嗓。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓污呼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親包竹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子燕酷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容