Apache Pig 中的区间交集
Posted
技术标签:
【中文标题】Apache Pig 中的区间交集【英文标题】:Intersection of Intervals in Apache Pig 【发布时间】:2014-04-16 15:09:20 【问题描述】:在 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 来为我完成这项工作,但似乎 Pig 应该能够做到这一点,而无需求助于自定义 UDF。
【问题讨论】:
【参考方案1】:这不是一个有效的解决方案,我建议编写一个 UDF 来执行此操作。
将数据集与自身连接以获得所有组合的叉积。在 pig 中,很难将某些内容与自身连接起来,因此您只需像加载两个单独的数据集一样行事。在叉积之后,您最终会得到类似的数据
1,A,1500,2000,1,A,1500,2000
1,A,1500,2000,2,A,1900,3000
.....
此时需要满足四个条件,
“where”字段匹配 自连接中的 ID 1 和 2 不匹配(因此您不会返回与自身相交的相同 ID) 被比较的第二组的开始时间应大于第一组的开始时间,小于第一组的结束时间此代码应该可以工作,可能在某处有语法错误,因为我无法对其进行测试,但应该可以帮助您编写所需的内容。
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;
【讨论】:
【参考方案2】:跨越大型集合会使数据膨胀。
没有交叉的简单解决方案是划分区间并检查每个区间内的交叉点。
我正在解决类似的问题,完成后会提供代码示例。
【讨论】:
如果您等到获得代码示例后再发布答案会更有帮助。这实际上不是一个答案,只是对问题的重述/澄清。以上是关于Apache Pig 中的区间交集的主要内容,如果未能解决你的问题,请参考以下文章
Apache Pig 中的 HCatalog 可以只加载特定分区吗?