zoukankan      html  css  js  c++  java
  • python的udf编写例子

    转载:https://blog.csdn.net/knidly/article/details/80265616

    简介

    Hive为我们提供了众多的内置函数,但是在实际的运用过程中仍然不能满足我们所有的需求.hive是用java开发的,本身提供了使用java去开发UDF的方式.而这里我们采用python的方式去实现UDF函数.

    DEMO实现

    我们这里用python自定义函数,去实现一个方法,利用身份证号去判断性别(18位身份证的倒数第二位偶数为女,奇数为男.15位身份证的倒数第一位偶数为女,奇数为男.).其实这个需求可以使用hive自带的function去进行解决.我们接下来使用2种方式去实现这个需求.

    数据准备

    我们在hive上创建一个external表(名字person表),执行如下代码:

    create external table person(
    name string,
    idcard string)
    ROW FORMAT DELIMITED 
    FIELDS TERMINATED BY '	'
    STORED as TEXTFILE;

    该表两个字段,一个为name,另一个为idcard 

    数据格式如下:

    neil    411326199402110030
    pony    41132519950911004x
    jcak    12312423454556561
    tony    412345671234908

    field分隔符使用  

    我们将数据放入hive的warehouse中:

    hdfs dfs -put person.txt /user/hive/warehouse/test_neil.db/person

    执行select,我们发现数据已经进入到hive了.

    使用Hive Function去实现

    我们可以执行一下的hql去实现

    select idcard,
    case when length(idcard) = 18 then
                 case when substring(idcard,-2,1) % 2 = 1 then '' 
                 when substring(idcard,-2,1) % 2 = 0 then '' 
                 else 'unknown' end 
         when length(idcard) = 15 then 
                case when substring(idcard,-1,1) % 2 = 1 then ''
                when substring(idcard,-1,1) % 2 = 0 then ''
                else 'unknown' end
         else '不合法' end 
    from person;

    得到的结果如下(beeline下):

    +---------------------+------+--+
    |       idcard        | _c1  |
    +---------------------+------+--+
    | 12312423454556561   | 不合法  |
    | 123124234545565     ||
    | 411325199308110030  ||
    | 41132519950911004x  ||

    UDF编写

    如下是我们的udf代码:

    # -*- coding: utf-8 -*-
    import sys
     
    for line in sys.stdin:
        detail = line.strip().split("	")
        if len(detail) != 2:
            continue
        else:
            name = detail[0]
            idcard = detail[1]
            if len(idcard) == 15:
                if int(idcard[-1]) % 2 == 0:
                    print("	".join([name,idcard,""]))
                else:
                    print("	".join([name,idcard,""]))
            elif len(idcard) == 18:
                if int(idcard[-2]) % 2 == 0:
                    print("	".join([name,idcard,""]))
                else:
                    print("	".join([name,idcard,""]))
            else:
                print("	".join([name,idcard,"身份信息不合法!"]))

    这里我们使用python的重定向,将hive控制台的输出进行split,split默认使用的为 .然后根据split后的idcard的倒数第二位进行判断这个人的性别.

     测试

    我们在hive中去执行查询时,报错的提示不是很详细.我们可以使用cat指令去测试python脚本的执行效果. 
    我们在终端中执行如下指令:

    cat person.txt|python person.py

    输入结果如下:

    neil    411325199308110030  男
    pony    41132519950911004x  女
    jack    12312423454556561   身份信息不合法!
    tony    123124234545565 男

    说明我们的解析是成功的.

    使用

    我们在hive中使用python定义的UDF函数要借助transform函数去执行. 
    transform函数的语法如下:

    SELECT TRANSFORM (<columns>)
    USING 'python <python_script>'
    AS (<columns>)
    FROM <table>;

    transfrom和as的columns的个数不必一致. 

    我们首先需要将我们的person.py加载入

    我们在hive中去执行如下代码:

    add file /xxx/person.py
    

    xxx为本地文件的路径. 
    然后使用transform函数执行:

    select transform(name,idcard) USING 'python person.py'  AS (name,idcard,gender) from person;
    

    java版本也需要打成jar包,使用add方式添加到hive中

    add jar jar_path;

    并且要创建函数:

    create function fun_name as 'java class name' USING jar 'hdfs_jar_path';
    // 上方为官方文档案例,下面的是我自己写的,属于临时函数,重启hive后失效
    create function fun_name as 'java class name';

    查询:

    select fun_name(字段...) from table_name;

    我们同样可以得到如下的结果:

    neil    411325199308110030  男
    pony    41132519950911004x  女
    jack    12312423454556561   身份信息不合法!
    tony    123124234545565
  • 相关阅读:
    什么是响应式设计?响应式设计的基本原理是什么?响应式设计的优缺点?
    你了解的浏览器兼容问题有哪些?
    简述网页中常见图片格式及特点?
    标签应该如何合理嵌套?
    你能想出几种方法让元素在页面中消失?
    为什么要初始化 CSS 样式?哪些样式需要初始化?
    文本溢出显示省略号如何实现?
    vue 几个典型的坑
    vue指令 v-if与 v-show的区别
    vuex的demo
  • 原文地址:https://www.cnblogs.com/to-here/p/15428213.html
Copyright © 2011-2022 走看看