我的输入数据集有3列,架构如下所示:
ActivityDate,EventId,EventDate
现在,使用pig我需要在一个输出文件中派生如下所示的多个变量:
1)ActivityDate> = EventDate -30天后的所有事件ID 2)ActivityDate> = EventDate -60天后的所有事件ID 3)ActivityDate> = EventDate -90天后的所有事件ID
我有30多个这样的变量。如果它是一个变量,我们可以使用简单的FILTER来过滤数据。
我正在考虑任何UDF实现,它将包作为输入,并根据每个参数的上述条件返回事件ID的计数。
汇总猪中多列数据的最佳方法是什么?
答案 0 :(得分:0)
我建议创建另一个包含所有阈值并与文件交叉连接的文件。 所以你会有一个包含以下内容的文件:
30
60
90
等
这样读:
grouping = load 'grouping.txt' using PigStorage(',') as (groups:double);
然后做:
data_with_grouping = cross data, grouping;
然后有这个二元条件:
data_with_binary_condition = foreach data_with_grouping generate ActivityDate, EventId, EventDate, groups, (ActivityDate >= EventDate - groups ? 1 : 0) as binary_condition;
现在,您将拥有一个包含阈值的列和一个包含二进制变量的列,该列可以告诉您ID是否符合条件。
你可以过滤掉binary_condition中的所有零,然后在groups列上进行分组:
data_with_binary_condition_filtered = filter data_with_binary_condition by (binary_condition != 0);
grouped_by_threshold = group data_with_binary_condition_filtered by groups;
count_of_IDS = foreach grouped_by_threshold generate group, COUNT(data_with_binary_condition.EventId);
我希望这有效。显然,我没有为你调试,因为我没有你的文件。 此代码将花费更多时间运行,但它将生成您需要的输出而无需UDF。
答案 1 :(得分:0)
如果我正确理解您的问题,您希望在30天块(例如1到30,31到60,61到90等等)中划分EventDate和ActivityDate之间的差异,然后计算每个块的频率。
在这种情况下,我只需重新排列上面的等式来创建变量'range',如下所示:
// assuming input contains 3 columns ActivityDate, EventId, EventDate
// dividing the difference between ED and AD by 30 and casting it to int, so that 1 block is represented by 1 integer.
input1 = FOREACH input GENERATE (int)((EventDate - ActivityDate) / 30) as range;
output1 = GROUP input1 BY range;
output2 = FOREACH output1 GENERATE group AS range, COUNT(range) as count;
希望这有帮助。