Python:对包含浮点值的pig元组求和

2024-07-03 05:34:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Pig/Python比较陌生,需要帮助。试图写一个猪的脚本来协调财务数据。使用的参数遵循如下语法(grand\u 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作为参数传递,并定义为:

^{pr2}$

我稍后会将$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'

我尝试了很多方法,试图将数组值转换为数值,并将其转换为float,以便可以求和,但都没有成功。在

有什么想法吗???谢谢你的关注!在


Tags: ofthelineprodresultregionvaluessum
2条回答

你可以在猪身上做这个。在

首先,指定架构中的数据类型。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;

很可能您的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 也可以:

^{pr2}$

在这种情况下,你会很高兴得到True而不是1,而{}而不是0:

^{3}$

相关问题 更多 >