我想用 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 的第一个组语句之后,也生成其他列,这就是您将有 avg 和 col6 具有相同的关系。
-
加载您的数据
根据需要对数据进行分组
计算 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 值的主要内容,如果未能解决你的问题,请参考以下文章