日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

学习笔记Hive(七)—— 自定义函数

發布時間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 学习笔记Hive(七)—— 自定义函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、自定義函數簡介

1.1、函數類型

UDF:用戶定義函數
UDF操作作用于單個數據行,并且產生一個數據行作為輸出。大多數函數都屬于這一類(比如數學函數和字符串函數)

UDAF:用戶定義聚集函數
UDAF 接受多個輸入數據行,并產生一個輸出數據行。像COUNT和MAX這樣的函數就是聚集函數。

UDTF:用戶定義表生成函數
UDTF 操作作用于單個數據行,并且產生多個數據行。比如explode。


二、自定義UDF

定義一個udf,實現根據輸入的日期,輸出一個時段, 2:00-5:00凌晨,5:00-12:00為上午,12:00-14:00為中午,14:00-17:00為下午,17:00-19:00為傍晚,19:00-23:00為晚上,23:00-2:00為深夜

  • 繼承UDF
  • 定義evaluate方法

    測試數據:
2019-12-12 10:38:26 2019-12-12 17:00:00 2016-01-22 19:23:22 2018-04-02 03:12:00

2.1、步驟:創建臨時函數或永久函數

1、創建臨時函數
1.上傳自定義udf的jar到Linux (將自定義函數打包成datetime.jar并長傳到/opt下)
2.在Hive CLI執行:add jar /opt/dateudf.jar;
3.在Hive CLI執行:create temporary function datetotime as 'demo.DateUDF';
(注意:創建臨時函數只有退出hive就不能再使用)


2、創建永久函數
1.把自定義函數的jar上傳到hdfs中
2.創建永久函數:create function datetotime as 'demo.DateUDF' using jar 'hdfs://master:8020/user/root/dateudf.jar’;



2.2、刪除自定義函數

刪除函數:drop [temporary] function [if exists] [dbname.]函數名;

例:刪除永久函數(臨時的就沒必要了,因為一退出就沒了)


三、自定義UDAF

求平均數
1.需繼承UDAF;
2.內部靜態類需繼承UDAFEvaluator抽象類,重寫方法init(),iterate(),terminatePartial(),merge(),terminate()。

init() 初始化 一般負責初始化內部字段,通常初始化用來存放最終結果的變量 iterate() 每次都會對一個新的值進行聚合計算時都調用該方法,一般會根據計算結果更新用來存放最終結果的變量,如果計算正確或者輸入值合法就返回true terminatePartial() 這個方法直譯過來是"終止部分",部分聚合結果的時候調用該方法 必須返回一個封裝了聚合計算當前狀態的對象,類似于 MapReduce的combiner merge() 接受來自 terminatePartial的返回結果,進行合并,hive合并兩部分聚合的時候回調用這個方法 terminate() 終止方法 返回最終聚合函數結果


測試數據:

1,700,1200 2,1201,1400 3,1401,2000 4,2001,3000 5,3001,9999

自定義函數:

package demo;import org.apache.hadoop.hive.ql.exec.UDAF; import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;public class UDAFAverage extends UDAF{public static class AvgStat{private int mcount;private double msum;} public static class AvgEvaluator implements UDAFAverage{AvgStat avgStat;public AvgEvaluator() {super();avgStat=new AvgStat();init(); }@Overridepublic void init() {avgStat.mcount=0;avgStat.msum=0;}/*** 介紹原始數據并進行內部輪轉* @return*/public boolean iterate(Double o) {if(o!=null) {avgStat.mcount++;avgStat.msum+=o;}return true;}/*** 接收iterate遍歷結束后的輸出結果進行初次聚集,類似Combiner* @return*/public AvgStat terminatePartial() {if(avgStat.mcount==0)return null;else return avgStat;}public boolean merge(AvgStat otheravgState) {if(otheravgState!=null) {avgStat.mcount+=otheravgState.mcount;avgStat.msum+=otheravgState.msum;}return true;}/*** terminate返回最終的聚集函數結果 * * @return*/public Double terminate() {if(avgStat.mcount==0)return null;else return avgStat.msum/avgStat.mcount; }} }

接下來就是創建臨時函數或永久函數了。。。


四、自定義UDTF

定義一個UDTF,可以將“商品1:價格1,商品2:價格2”格式的一列數據解析成商品,價格兩個字段

1.繼承GenericUDTF,實現initialize, process, close三個方法
2.其中initialize方法主要是判斷輸入類型并確定返回的字段類型。
3.process方法對udft函數輸入的每一行進行操作,通過調用forward方法返回一行或多行數據。
4.close方法在process調用結束后調用,用于進行其它一些額外操作,只執行一次。

測試數據:

shop1:20,shop2:30 shop3:40,shop4:30,shop5:10

自定義函數:

import java.util.ArrayList;import org.apache.hadoop.hive.ql.exec.UDFArgumentException; import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException; import org.apache.hadoop.hive.ql.metadata.HiveException; import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory; import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory; import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;public class UDTFExplode extends GenericUDTF{/*** 進行輸入類型判斷,定義輸出字段和類型* 輔助類objectInspector幫助使用者訪問需要序列化或者反序列化的對象*/ @Overridepublic StructObjectInspector initialize(ObjectInspector[] argOIs) throws UDFArgumentException {if(argOIs.length!=1) {throw new UDFArgumentLengthException("UDTFExplode takes only one argument");}if(argOIs[0].getCategory()!=ObjectInspector.Category.PRIMITIVE) {throw new UDFArgumentException("UDTFExplode takes string as a parameter");}ArrayList<String> fieldNames = new ArrayList<String>(); ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();fieldNames.add("shop");fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);fieldNames.add("volume");fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames,fieldOIs);}@Overridepublic void close() throws HiveException {// TODO Auto-generated method stub} /*** 處理輸入的數據:商品1:銷量1,商品2:銷量2....* 返回多行,每行新增兩個字段shop,volumn*/ @Overridepublic void process(Object[] arg0) throws HiveException {String[] input = arg0[0].toString().split(",");for(String shop_vol:input) {String[] input_split = shop_vol.split(":");forward(input_split);}} }

接下來就是創建臨時函數或永久函數了。。。


4.1、UDTF使用方法

1、直接在select中使用
(udtfexplode:自定義函數)

select udtfexplode(datetime) as (shop,volume) from test;

2、和lateral view一起使用,執行過程相當于單獨執行了兩次抽取,然后合并到一個表里。

select datetime,t.shop,t.volume from test lateral view udtfexplode(datetime) t as shop,volume;

總結

以上是生活随笔為你收集整理的学习笔记Hive(七)—— 自定义函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。