gpt4 book ai didi

java - Pig latin 中扁平运算符的模式

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:21:10 24 4
gpt4 key购买 nike

我最近在工作中遇到了这个问题,是关于pig flatten的。我用一个简单的例子来表达它

两个文件
===文件1===
1_a
2_b
4_d

===file2(制表符分隔)===
1个
2乙
3c

pig 脚本1:

a = load 'file1' as (str:chararray);
b = load 'file2' as (num:int, ch:chararray);
a1 = foreach a generate flatten(STRSPLIT(str,'_',2)) as (num:int, ch:chararray);
c = join a1 by num, b by num;
dump c; -- exception java.lang.String cannot be cast to java.lang.Integer

pig 脚本2:

a = load 'file1' as (str:chararray);
b = load 'file2' as (num:int, ch:chararray);
a1 = foreach a generate flatten(STRSPLIT(str,'_',2)) as (num:int, ch:chararray);
a2 = foreach a1 generate (int)num as num, ch as ch;
c = join a2 by num, b by num;
dump c; -- exception java.lang.String cannot be cast to java.lang.Integer

pig 脚本3:

a = load 'file1' as (str:chararray);
b = load 'file2' as (num:int, ch:chararray);
a1 = foreach a generate flatten(STRSPLIT(str,'_',2));
a2 = foreach a1 generate (int)$0 as num, $1 as ch;
c = join a2 by num, b by num;
dump c; -- right

我不知道为什么脚本1,2错误而脚本3正确,我也想知道是否有更简洁的表达式来获得关系c,谢谢。

最佳答案

您没有使用 PigStorage 有什么特别的原因吗?因为它可以让您的生活变得更轻松 :)。

a = load '/file1' USING PigStorage('_') AS (num:int, char:chararray);
b = load '/file2' USING PigStorage('\t') AS (num:int, char:chararray);
c = join a by num, b by num;
dump c;

另请注意,在 file1 中,您使用下划线作为分隔符,但您将“-”作为 STRSPLIT 的参数。

编辑:我在你提供的脚本上花了更多时间;脚本 1 和 2 确实不起作用,脚本 3 也像这样工作(没有额外的 foreach):

a = load 'file1' as (str:chararry);
b = load 'file2' as (num:int, ch:chararry);
a1 = foreach a generate flatten(STRSPLIT(str,'_',2));
c = join a1 by (int)($0), b by num;
dump c;

至于问题的根源,我会大胆猜测并说它可能与此(as stated in Pig Documentation)结合 pig 的运行周期优化有关:

If you FLATTEN a bag with empty inner schema, the schema for the resulting relation is null.

在您的情况下,我相信 STRSPLIT 结果的架构在运行时之前是未知的。

编辑2:好的,这是我的理论解释:

This is the complete -explain- output for script 2this is for script 3 .我将把有趣的部分粘贴在这里。

|---a2: (Name: LOForEach Schema: num#288:int,ch#289:chararray)
| | |
| | (Name: LOGenerate[false,false] Schema: num#288:int,ch#289:chararray)ColumnPrune:InputUids=[288, 289]ColumnPrune:OutputUids=[288, 289]
| | | |
| | | (Name: Cast Type: int Uid: 288)
| | | |
| | | |---num:(Name: Project Type: int Uid: 288 Input: 0 Column: (*))

以上部分用于脚本 2;看最后一行。它假定 flatten(STRSPLIT) 的输出将具有 integer 类型的第一个元素(因为您以这种方式提供了架构)。但实际上 STRSPLIT 有一个 null 输出模式,它被视为 bytearray 字段;所以 flatten(STRSPLIT) 的输出实际上是 (n:bytearray, c:bytearray)。因为您提供了模式,pig 尝试将 java 转换(到 a1 的输出)到 num 字段;失败,因为 num 实际上是一个 java String 表示为 bytearray。由于此 java-cast 失败,pig 甚至没有尝试在上面的行中进行显式转换。

让我们看看脚本 3 的情况:

|---a2: (Name: LOForEach Schema: num#85:int,ch#87:bytearray)
| | |
| | (Name: LOGenerate[false,false] Schema: num#85:int,ch#87:bytearray)ColumnPrune:InputUids=[]ColumnPrune:OutputUids=[85, 87]
| | | |
| | | (Name: Cast Type: int Uid: 85)
| | | |
| | | |---(Name: Project Type: bytearray Uid: 85 Input: 0 Column: (*))

请看最后一行,此处 a1 的输出被正确处理为 bytearray,这里没有问题。现在看看倒数第二行; pig 尝试(并成功)进行从 bytearrayinteger 的显式转换操作。

关于java - Pig latin 中扁平运算符的模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12213659/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com