【问题标题】:Python: Summing a pig tuple containing float valuesPython:对包含浮点值的猪元组求和
【发布时间】:2016-04-07 18:41:03
【问题描述】:

我对 Pig/Python 还很陌生,需要帮助。尝试编写一个协调财务数据的 Pig 脚本。使用的参数遵循类似 (grand_tot, x1, x2,... xn) 的语法,这意味着第一个值应该等于剩余值的总和。

我不知道如何单独使用 Pig 来完成此任务,因此我一直在尝试编写 Python UDF。 Pig 将一个元组传递给 Python;如果 x1:xn 之和等于 grand_tot,则 Python 应向 Pig 返回“1”以表明数字匹配,否则返回“0”。

这是我目前所拥有的:

register 'myudf.py' using jython as myfuncs; 
A = LOAD '$file_nm' USING PigStorage(',') AS (grand_tot,west_region,east_region,prod_line_a,prod_line_b, prod_line_c, prod_line_d); 
A1 = GROUP A ALL; 
B = FOREACH A1 GENERATE TOTUPLE($recon1) as flds; 
C = FOREACH B GENERATE myfuncs.isReconciled(flds) AS res;
DUMP C;

$recon1作为参数传递,定义为:

grand_tot, west_region, east_region

我稍后会将 $recon2 传递为:

grand_tot, prod_line_a, prod_line_b, prod_line_c, prod_line_d

示例数据行(在 $file_nm 中)如下所示:

grand_tot,west_region,east_region,prod_line_a,prod_line_b, prod_line_c, prod_line_d
10000,4500,5500,900,2200,450,3700,2750
12500,7500,5000,3180,2770,300,3950,2300
9900,7425,2475,1320,460,3070,4630,1740

最后...这是我正在尝试使用 Python UDF 代码执行的操作:

@outputSchema("result")
def isReconciled(arrTuple):
    arrTemp = []
    arrNew = []
    string1 = ""
    result = 0
    ## the first element of the Tuple should be the sum of remaining values
    varGrandTot = arrTuple[0]
    ## create a new array with the remaining Tuple values
    arrTemp = arrTuple[1:]

    for item in arrTuple:
        arrNew.append(item)

    ## sum the second to the nth values
    varSum = sum(arrNew)

    ## if the first value in the tuple equals the sum of all remaining values
    if varGrandTot = varSum then:
        #reconciled to the penny
        result = 1
    else:
        result = 0

    return result

我收到的错误信息是: + 不支持的操作数类型:'int' 和 'array.array'

我尝试了许多尝试将数组值转换为数字并转换为浮点数以便求和的方法,但没有成功。

有什么想法吗???感谢收看!

【问题讨论】:

    标签: python tuples apache-pig


    【解决方案1】:

    您可以在 PIG 本身中执行此操作。

    首先,指定架构中的数据类型。 PigStorage 将使用 bytearray 作为默认数据类型。因此您的 python 脚本抛出错误。看起来您的示例数据具有 int 但在您的问题中您提到了 float。

    其次,添加从第二个字段或您选择的字段开始的字段。

    第三,使用 bincond 操作符检查第一个字段值与总和。

    A = LOAD '$file_nm' USING PigStorage(',') AS (grand_tot:float,west_region:float,east_region:float,prod_line_a:float,prod_line_b:float, prod_line_c:float, prod_line_d:float); 
    A1 = FOREACH A GENERATE grand_tot,SUM(TOBAG(prod_line_a,prod_line_b,prod_line_c,prod_line_d)) as SUM_ALL; 
    B = FOREACH A1 GENERATE (grand_tot == SUM_ALL ? 1 : 0); 
    DUMP B;
    

    【讨论】:

    • 这个工作,有一些调整。在没有 Python 的情况下,性能也有所提高(奖励)。谢谢。
    • @JaneQDoe Cool。如果回答了您的问题,请标记为回答
    【解决方案2】:

    很可能,您的arrTuple 不是数字数组,但某些项目是数组。

    要检查它,请通过添加一些检查来修改您的代码:

    @outputSchema("result")
    def isReconciled(arrTuple):
        # some checks
        tmpl = "Item # {i} shall be a number (has value {itm} of type {tp})"
        for i, num in enumerate(arrTuple):
            msg = templ.format(i=i, itm=itm, tp=type(itm))
            assert isinstance(arrTuple[0], (int, long, float)), msg
        # end of checks
    
        arrTemp = []
        arrNew = []
        string1 = ""
        result = 0
        ## the first element of the Tuple should be the sum of remaining values
        varGrandTot = arrTuple[0]
        ## create a new array with the remaining Tuple values
        arrTemp = arrTuple[1:]
    
        for item in arrTuple:
            arrNew.append(item)
    
        ## sum the second to the nth values
        varSum = sum(arrNew)
    
        ## if the first value in the tuple equals the sum of all remaining values
        if varGrandTot = varSum then:
            #reconciled to the penny
            result = 1
        else:
            result = 0
    
        return result
    

    它很可能会在其中一项上引发AssertionFailed 异常。阅读 要了解的断言消息,哪个项目造成了麻烦。

    无论如何,如果你想返回 0 或 1 如果第一个数字等于数组其余部分的总和,则如下 也可以:

    @outputSchema("result")
    def isReconciled(arrTuple):
        if arrTuple[0] == sum(arrTuple[1:]):
            return 1
        else:
            return 0
    

    如果你得到True而不是1和False而不是0,你会很高兴:

    @outputSchema("result")
    def isReconciled(arrTuple):
        return arrTuple[0] == sum(arrTuple[1:])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多