我想用 PIG 中的 AVG 替换 NULL 值

Posted

技术标签:

【中文标题】我想用 PIG 中的 AVG 替换 NULL 值【英文标题】:I want to replace NULL values by AVG in PIG 【发布时间】:2016-08-08 06:03:12 【问题描述】:

这是我的代码:

    claims = LOAD 'Darshan/automobile_insurance_claims.csv' USING  PigStorage(',') AS (claim_id:chararray, policy_master_id:chararray, registration_no:chararray, engine_no:chararray, chassis_no:chararray, customer_id:int, Col6:int,first_name:chararray, last_name:chararray,street:chararray,address:chararray,    city:chararray, zip:long,gender:chararray, claim_date:chararray, garage_city:chararray, bill_no:long, claim_amount:double, garage_name:chararray,claim_status:chararray);  

    grp_all = group claims all; 

    avg = foreach  grp_all generate AVG(claims.Col6); 
    grp = group claims by claim_id;  

    m = foreach grp generate group, ((Col6 IS NULL) ? avg : Col6);   

结果: dump avg; #33.45

----------------------------------- -------------------------------------------------- ------------------------------------------------在 Col6 中替换 NULL 值时显示以下错误(即年龄): 原因: 无效的标量投影:avg:需要从关系中投影列才能用作 s 卡拉尔 在 org.apache.pig.parser.LogicalPlanGenerator.var_expr(LogicalPlanGenerator.java:10947) 在 org.apache.pig.parser.LogicalPlanGenerator.expr(LogicalPlanGenerator.java:10164) 在 org.apache.pig.parser.LogicalPlanGenerator.bin_expr(LogicalPlanGenerator.java:11992) 在 org.apache.pig.parser.LogicalPlanGenerator.projectable_expr(LogicalPlanGenerator.java:11104) 在 org.apache.pig.parser.LogicalPlanGenerator.var_expr(LogicalPlanGenerator.java:10815) 在 org.apache.pig.parser.LogicalPlanGenerator.expr(LogicalPlanGenerator.java:10164) 在 org.apache.pig.parser.LogicalPlanGenerator.flatten_generated_item(LogicalPlanGenerator.java:7493) 在 org.apache.pig.parser.LogicalPlanGenerator.generate_clause(LogicalPlanGenerator.java:17595) 在 org.apache.pig.parser.LogicalPlanGenerator.foreach_plan(LogicalPlanGenerator.java:15987) 在 org.apache.pig.parser.LogicalPlanGenerator.foreach_clause(LogicalPlanGenerator.java:15854) 在 org.apache.pig.parser.LogicalPlanGenerator.op_clause(LogicalPlanGenerator.java:1933) 在 org.apache.pig.parser.LogicalPlanGenerator.general_statement(LogicalPlanGenerator.java:1102) 在 org.apache.pig.parser.LogicalPlanGenerator.statement(LogicalPlanGenerator.java:560) 在 org.apache.pig.parser.LogicalPlanGenerator.query(LogicalPlanGenerator.java:421) 在 org.apache.pig.parser.QueryParserDriver.parse(QueryParserDriver.java:188) ... 17 更多 2016-08-08 05:51:07,297 [main] 错误 org.apache.pig.tools.grunt.Grunt - 错误 1200:Pig 脚本无法解析: 无效的标量投影:avg:需要从关系中投影列才能用作 s 标量。

第 11 行是:m = foreach grp generate group, ((Col6 IS NULL) ? avg : Col6);

【问题讨论】:

m = foreach grp generate group, ((claims.Col6 IS NULL) ? avg.$0 : claim.Col6); 请提供样本数据集.. @ankur 汽车保险索赔.csv:github.com/pradeep-pasupuleti/pig-design-patterns/blob/master/… 【参考方案1】:

Darshan,这看起来不像您正在尝试的逻辑问题。您可以将 NULLs 替换为 AVG,但这里的问题是列的 projection

要解决这个问题,请再次访问您的代码,您可能会发现 AVG 处于不同的关系中,并且您正在从不同的关系中访问它。

在您的代码中,“avg”是关系而不是列,如果我理解正确,在您生成 AVG 的第一个组语句之后,也生成其他列,这就是您将有 avgcol6 具有相同的关系。

    加载您的数据 根据需要对数据进行分组 计算 AVG 并生成其他列

如果你愿意,你可以在同一个 FOREACH 中应用这个替换逻辑。

如果您仍然遇到任何问题,请告诉我。

【讨论】:

【参考方案2】:

您收到错误是因为 avg 是一个关系,您需要使用关系 avg 中的一列。更正您的最后一条 PIG 语句以引用关系 avg 中的第一列,像这样

m = foreach grp generate group, ((claims.Col6 IS NULL) ? (double)avg.$0 : claims.Col6);

或者,您可以命名列并引用它,就像这样

avg = foreach  grp_all generate AVG(claims.Col6) AS AVG_Col6; 
grp = group claims by claim_id;  
m = foreach grp generate group, ((claims.Col6 IS NULL) ? (double)avg.AVG_Col6 : claims.Col6);  

【讨论】:

是的,这是我正在寻找的完美解决方案。但是得到另一个错误:BinCond 不支持的输入类型:左侧:双;右手边:bag .......它以claims.Col6作为Bag 尝试像这样转换 avg.AVG_Col6,我怀疑它是 AVG_Col6 而不是 Claims.Col6,因为 Claims.Col6 是一个字段,它的类型是 int。 m = foreach grp 生成组,((claims.Col6 IS NULL)?(double)avg.AVG_Col6:claims.Col6);我已经编辑了答案 avg.Col6 或 avg.AVG_Col6 没问题......它正在将 claim.Col6 作为 BAG。我必须将此claims.Col6 更改为Double。 (错误:BinCond 不支持的输入类型:左侧:double;右侧:bag) 你不能像avg_col6一样投射吗? 不。它显示错误。不能从 Bag 施法到 Double。【参考方案3】:

这是我的查询的最终代码:

claims = LOAD 'Darshan/automobile_insurance_claims.csv' USING  PigStorage(',') AS 
         (claim_id:chararray, policy_master_id:chararray, registration_no:chararray, 
         engine_no:chararray, chassis_no:chararray, customer_id:int, Col6:int,
         first_name:chararray, last_name:chararray,street:chararray,address:chararray,
         city:chararray, zip:long,gender:chararray, claim_date:chararray,
         garage_city:chararray, bill_no:long, claim_amount:double,
         garage_name:chararray,claim_status:chararray);  

grp_all = group claims all; 
avg = foreach  grp_all generate AVG(claims.Col6); 
grp = group claims by claim_id; 

result = foreach grp  
             val = foreach claims generate ((Col6 IS NULL) ? avg.$0 : Col6);
             generate group, val; 
         ;

这里是数据集automobile_insurance_claims.csv的链接

【讨论】:

以上是关于我想用 PIG 中的 AVG 替换 NULL 值的主要内容,如果未能解决你的问题,请参考以下文章

Apache Pig:用字符串替换 null

SQL:具有 NULL 值的 AVG

strcpy... 想用 strcpy_mine 替换,它将 strncpy 和 null 终止

仅当它在 Pig 中的内部引号(“”)时才替换逗号(,)

用值替换 NULL

如何为 AVG 函数投射 Pig 字段