引入新的內置和高階函數為複雜數據類型在Apache 2.4火花
2018年11月16日, 在工程的博客
Apache 2.4火花引入了29個新的內置函數操縱複雜類型(例如,數組類型),包括高階函數。
在火花2.4之前,直接操縱複雜類型,通常有兩種解決方案:1)嵌套結構爆炸成單個行,並應用一些函數,然後再創建結構2)構建一個用戶定義函數(UDF)。
相比之下,新的內置函數可以直接操縱複雜類型,和高階函數可以操縱複雜的值和一個匿名lambda函數類似於udf但具有更好的性能。
在這個博客中,通過一些例子,我們將展示一些新的內置函數,以及如何使用它們來處理複雜的數據類型。
典型解決方案
讓我們回顧一下典型的解決方案與下麵的例子。
選項1 -爆炸和收集
我們使用爆炸數組分解成單獨的行和評估val + 1
數組,然後使用collect_list調整如下:
選擇id,collect_list (val+1)作為瓦爾斯從(選擇id,爆炸(val)作為瓦爾從input_tbl) x集團通過id
這是容易出錯,效率低下的原因有三。首先,我們必須細心地確保想起數組是由完全從原始數組通過分組他們獨特的關鍵。第二,我們需要一個group by
,這意味著一個洗牌操作;不能保證洗牌操作保持振作數組的元素順序從原始數組中。最後,它是昂貴的。
選項2 -用戶定義函數
接下來,我們使用Scala UDF將Seq (Int)和它的每個元素加1:
def addOne (值:Seq [Int):Seq [Int]={values.map (價值=>價值+1)}val plusOneInt=spark.udf。注冊(“plusOneInt addOne (_: Seq [Int):Seq [Int])
或者我們也可以使用Python UDF,然後:
選擇id, plusOneInt (val)作為瓦爾斯從input_tbl
這是簡單快捷,不遭受正確性缺陷,但它仍然可能是低效的,因為數據序列化到Scala或Python可以是昂貴的。
你可以看到一個筆記本的例子博客,發表並嚐試它們。
新的內建函數
讓我們看看新的內置函數直接操縱複雜類型。的筆記本列出了每個函數的例子。每個函數的簽名和參數注釋與各自的類型T和U表示數組元素類型和K、V地圖和值類型。
高階函數
為進一步操作數組和地圖類型,我們使用已知的SQL語法匿名lambda函數和高階函數lambda函數作為參數。
lambda函數的語法如下:
參數- >函數身體(argument1, argument2,…)- - - >函數身體
左邊的符號- >定義了參數列表,和右側定義函數體可以使用參數和其他變量計算新值。
變換與匿名Lambda函數
讓我們看看這個例子變換
函數使用一個匿名lambda函數。
這裏我們有一個表的數據包含三列:一個關鍵的整數;整數的數組的值;和nested_values整數的數組的數組。
關鍵 | 值 | nested_values |
---|---|---|
1 | (1、2、3) | [[1,2,3],[],[4,5]] |
當我們執行以下SQL:
選擇變換(值、元素- - - - - ->元素+1)從數據;
的變換
函數遍曆該數組和lambda函數,適用於每個元素加1,並創建一個新數組。
我們還可以使用其它變量除了參數,例如:鑰匙,這是來自於外部環境,表的一列,lambda函數:
選擇變換(值、元素- - - - - ->元素+鍵)從數據;
如果你想操作深度嵌套列,像nested_values在這種情況下,您可以使用嵌套的lambda函數:
選擇變換(nested_values,加勒比海盜- - - - - ->變換(加勒比海盜,元素- - - - - ->元素+關鍵+大小(arr)))從數據;
您可以使用關鍵
和加勒比海盜
內部lambda函數來自外部環境,表的一個列和一個外lambda函數的參數。
注意,您可以看到相同的例子作為典型的解決方案在筆記本上,和其他高階函數的例子包括筆記本的內置函數。
結論
火花24 2.4引入了新的內置函數,如array_union
,array_max /分鍾
等,和5個高階函數,如變換
,過濾器
等操縱複雜類型。在這整個列表和他們的例子筆記本。如果你有任何複雜的值,考慮使用他們,讓我們知道任何問題。
我們要感謝Apache引發社會的貢獻者Alex Vayda布魯斯·羅賓斯,迪倫古埃德,弗洛倫特·Pepin, H,華新高,Kazuaki Ishizaki, Marco Gaido Marek Novotny, Neha帕蒂爾,Sandeep辛格,和許多其他人。
閱讀更多
找到更多關於高階和內置函數,看到以下資源: