在Hadoop中,我有一组数据点,每个数据点都包含一个“startTime”和“endTime”,以毫秒为单位。我想在一个字段上分组然后识别包中的每个位置,其中一个数据点在开始/结束时间的意义上与另一个数据点重叠。例如,这里有一些数据:
0,A,0,1000
1,A,1500,2000
2,A,1900,3000
3,B,500,2000
4,B,3000,4000
5,B,3500,5000
6,B,7000,8000
我加载和分组如下:
inputdata = LOAD 'inputdata' USING PigStorage(',')
AS (id:long, where:chararray, start:long, end:long);
grouped = GROUP inputdata BY where;
理想的结果是
(1,2)
(4,5)
我写了一些不好的代码来为每一秒生成一个单独的元组并进行一些舍入,然后做一个集合交集,但这看起来非常低效,事实上它仍然不能正常工作。我没有调试糟糕的方法,而是希望使用良好的方法。
如何合理有效地获取重叠数据点的元组(id1,id2)?
我非常自在地编写Java UDF来为我做这项工作,但看起来猪应该能够做到这一点而不需要求助于自定义UDF。
答案 0 :(得分:0)
这不是一个有效的解决方案,我建议编写一个UDF来执行此操作。
自我将数据集与自身连接以获得所有组合的叉积。在猪身上,很难与自己联系起来,所以你就好像你正在加载两个独立的数据集一样。在交叉产品之后,您最终会得到像
这样的数据1,A,1500,2000,1,A,1500,2000
1,A,1500,2000,2,A,1900,3000
.....
此时,您需要满足四个条件
此代码应该可以使用,可能会出现语法错误,因为我无法对其进行测试,但应该可以帮助您编写所需内容。
inputdataone = LOAD 'inputdata' USING PigStorage(',')
AS (id:long, where:chararray, start:long, end:long);
inputdatatwo = LOAD 'inputdata' USING PigStorage(',')
AS (id:long, where:chararray, start:long, end:long);
crossProduct = CROSS inputdataone, inputdatatwo;
crossProduct =
FOREACH crossProduct
GENERATE inputdataone::id as id_one,
inputdatatwo::id as id_two,
(inputdatatwo::start-inputdataone::start>=0 AND inputdatatwo::start-inputdataone::end<=0 AND inputdataone::where==inputdatatwo::where?1:0) as intersect;
find_intersect = FILTER crossProduct BY intersect==1;
final =
FOREACH find_intersect
GENERATE id_one,
id_two;
答案 1 :(得分:0)
跨越大集合会使数据膨胀。
没有交叉的天真解决方案是划分间隔并检查每个间隔内的交叉点。
我正在处理类似的问题,并在完成后提供代码示例。