我在pig中有一个袋子,它已按键分组,其值为纬度和经度。我想为每个键计算任意两个(lat,long)对之间的最大距离;如果小于2,则输出应该为0。
例如,如果我的包是
{(1): (1.1, 1.1),
(1): (2.1, 2.1),
(1): (3.1, 3.1),
(2): (1.1, 1.1)
}
我的答案是
{(1): 314 (km)
(2): 0
}
计算两个(长、宽)对之间距离的方程式为:
(((lat1 - lat2) * pi() * 3959 / 180)^2 + ((long1 - long2) * 2 * pi() * 3959 * cos(((lat2 + lat1) / 2) * .0174533) / 360)^2)^(1/2)
有没有一种简单的方法可以创建一个python udf来实现这一点?谢谢你的帮助。
以下是我想到的步骤:
-
打开袋子。这将使用生成元组(在您的示例中)
(1,1.1,1.1)(1,2.1,2.1)(1,3.1,3.1)(2,1.1,1.1)
-
执行上面的步骤两次,将得到的关系命名为两个不同的名称:r1和r2。
-
通过关键字字段将r1和r2连接起来。这将为每个关键创建一个笛卡尔乘积
通过密钥加入r1,通过密钥加入r2
这将导致
(1,1.1,1.1,1,1.1,1.1)
(1,1.1,1.1,1,2.1,2.1)
(1,1.1,1.1,1,3.1,3.1)
(1,2.1,2.1,1,1.1,1.1)
(1,2.1,2.1,1,2.1,2.1)
(1,2.1,2.1,1,3.1,3.1)
(1,3.1,3.1,1,1.1,1.1)
(1,3.1,3.1,1,2.1,2.1)
(1,3.1,3.1,1,3.1,3.1)
(2,1.1,1.1,2,1.1,1.1)
此列表包含每个键的所有可能配对。作为奖励,对于只有一个坐标的关键帧,您还可以获得一对该坐标。
- 使用数据流中的HaversineDistInMiles UDFhttp://datafu.incubator.apache.org/docs/datafu/1.2.0/datafu/pig/geo/HaversineDistInMiles.html
以计算每对坐标之间的距离。对于具有相同坐标的对,可以得到距离==0。
(datau是LinkedIn的一个很棒的实用程序UDF包。点击此处阅读:https://datafu.incubator.apache.org)
- 按键分组,并为每个键生成MAX(距离)。这将为您提供以英里为单位的最大距离。乘以1.6093,得到以KM为单位的距离
假设你的文件是这样的:
1 {(1.1,1.1),(2.1,2.1),(3.1,3.1)}
2 {(1.1,1.1)}
使用这个pig脚本:
register '/path/to/datafu-1.2.0.jar';
a = LOAD 'pigcoords.tsv' using PigStorage() as (A1:int, B1:bag{T:tuple(longitude:double, latitude:double)});
b = foreach a generate A1, FLATTEN(B1);
c = foreach a generate A1, FLATTEN(B1);
d = foreach (join b by A1, c by A1) generate $0..;
op = FOREACH d GENERATE b::A1 as key, datafu.pig.geo.HaversineDistInMiles(b::B1::latitude, b::B1::longitude, c::B1::latitude, c::B1::longitude) as distance;
res = FOREACH (group op by key) generate MAX(op.distance)*1.6093;
dump res;
检查我的github repo:https://github.com/csabakecskemeti/geo_clustering/tree/master/src/main/java/kecso/geotools/geodistance
这是一个用于地理距离计算的java UDF。您可以使用它来计算pairn上的距离,然后应用MAX函数。我希望这能有所帮助。