pig - 将数据从行转换为列,同时为特定行中不存在的字段插入占位符
Posted
技术标签:
【中文标题】pig - 将数据从行转换为列,同时为特定行中不存在的字段插入占位符【英文标题】:pig - transform data from rows to columns while inserting placeholders for non-existent fields in specific rows 【发布时间】:2014-02-20 19:31:47 【问题描述】:假设我在 HDFS 上有以下平面文件(我们称之为 key_value):
1,1,Name,Jack
1,1,Title,Junior Accountant
1,1,Department,Finance
1,1,Supervisor,John
2,1,Title,Vice President
2,1,Name,Ron
2,1,Department,Billing
这是我正在寻找的输出:
(1,1,Department,Finance,Name,Jack,Supervisor,John,Title,Junior Accountant)
(2,1,Department,Billing,Name,Ron,,,Title,Vice President)
换句话说,前两列形成一个唯一标识符(类似于 db 术语中的复合键),对于此标识符的给定值,我们希望输出中有一行(即最后两列 -是有效的键值对 - 只要标识符相同,就被压缩到同一行)。另请注意第二行中的空值,用于为唯一标识符为 (2, 1) 时缺少的主管片段添加占位符。
为此,我开始整理这个猪脚本:
data = LOAD 'key_value' USING PigStorage(',') as (i1:int, i2:int, key:chararray, value:chararray);
data_group = GROUP data by (i1, i2);
expected = FOREACH data_group
sorted = ORDER data BY key, value;
GENERATE FLATTEN(BagToTuple(sorted));
;
dump expected;
上面的脚本给了我以下输出:
(1,1,Department,Finance,1,1,Name,Jack,1,1,Supervisor,John,1,1,Title,Junior Accountant)
(2,1,Department,Billing,2,1,Name,Ron,2,1,Title,Vice President)
请注意,缺少 Supervisor 的空占位符未出现在第二条记录中(这是预期的)。如果我可以将这些空值放置到位,那么摆脱冗余列似乎只是另一个投影的问题(前两个被复制多次 - 每个键值对一次)。
没有使用 UDF,有没有办法在 pig 中使用内置函数来完成这个?
更新:正如 WinnieNicklaus 正确指出的那样,输出中的名称是多余的。所以输出可以浓缩为:
(1,1,Finance,Jack,John,Junior Accountant)
(2,1,Billing,Ron,,Vice President)
【问题讨论】:
为什么要在每一行都有字段的名称? 我最初没有在嵌套中对每个进行排序,因此键值对在不同行中以可能不同的顺序输出。你说的对。我不再需要每一行中的名称,因为可以从行中值的位置推断出给定值所关联的名称。因此,让我们假设名称被删除在输出中。但是,对于第二条记录中给定字段(例如主管)的缺失值,我们仍然需要占位符(null)。 你有少数可能的名字吗? 名字的数量比较少——大约250个左右。 哈哈,我希望有 5 或 10 之类的东西。我应该澄清一下,我说的是“主管”和“头衔”,而不是“杰克”或“罗恩”。还是250吗? 【参考方案1】:首先,让我指出,如果对于大多数行,大多数列都没有填写,那么 IMO 更好的解决方案是使用地图。内置的 TOMAP
UDF 结合 a custom UDF to combine maps 将使您能够做到这一点。
我确信有一种方法可以通过计算所有可能的键的列表来解决您的原始问题,用空值将其分解,然后丢弃也存在非空值的实例......但这会涉及大量的 MR 循环,非常丑陋的代码,我怀疑这并不比以其他方式组织数据更好。
您还可以编写一个 UDF 来接收一袋键/值对、另一袋所有可能的键,并生成您正在寻找的元组。这样会更清晰、更简单。
【讨论】:
感谢 WinnieNicklaus 及时回答这个问题(以及之前的问题)。非常感谢。由于仅使用内置函数(即不使用 UDF)没有干净的方法来完成手头的任务,因此我将接受您的回答。以上是关于pig - 将数据从行转换为列,同时为特定行中不存在的字段插入占位符的主要内容,如果未能解决你的问题,请参考以下文章