我有一个时间段内用户的Lat / Lon格式的位置数据集。我想计算这些用户旅行的距离。样本数据集:
|时间戳|用户|纬度|经度| | 1462838468 | 49B4361512443A4DA ... | 39.777982 | -7.054599 | | 1462838512 | 49B4361512443A4DA ... | 39.777982 | -7.054599 | | 1462838389 | 49B4361512443A4DA ... | 39.777982 | -7.054599 | | 1462838497 | 49B4361512443A4DA ... | 39.777982 | -7.054599 | | 1465975885 | 6E9E0581E2A032FD8 ... | 37.118362 | -8.205041 | | 1457723815 | 405C238E25FE0B9E7 ... | 37.177322 | -7.426781 | | 1457897289 | 405C238E25FE0B9E7 ... | 37.177922 | -7.447443 | | 1457899229 | 405C238E25FE0B9E7 ... | 37.177922 | -7.447443 | | 1457972626 | 405C238E25FE0B9E7 ... | 37.18059 | -7.46128 | | 1458062553 | 405C238E25FE0B9E7 ... | 37.177322 | -7.426781 | | 1458241825 | 405C238E25FE0B9E7 ... | 37.178172 | -7.444512 | | 1458244457 | 405C238E25FE0B9E7 ... | 37.178172 | -7.444512 | | 1458412513 | 405C238E25FE0B9E7 ... | 37.177322 | -7.426781 | | 1458412292 | 405C238E25FE0B9E7 ... | 37.177322 | -7.426781 | | 1465197963 | 6E9E0581E2A032FD8 ... | 37.118362 | -8.205041 | | 1465202192 | 6E9E0581E2A032FD8 ... | 37.118362 | -8.205041 | | 1465923817 | 6E9E0581E2A032FD8 ... | 37.118362 | -8.205041 | | 1465923766 | 6E9E0581E2A032FD8 ... | 37.118362 | -8.205041 | | 1465923748 | 6E9E0581E2A032FD8 ... | 37.118362 | -8.205041 | | 1465923922 | 6E9E0581E2A032FD8 ... | 37.118362 | -8.205041 |
我曾想过使用自定义聚合器函数,但似乎没有Python支持。此外,操作需要按特定顺序在相邻点上完成,因此我不知道自定义聚合器是否可行。
我也查看了reduceByKey
但距离函数似乎没有满足运算符要求。
有没有办法在Spark中以有效的方式执行此操作?
答案 0 :(得分:6)
它看起来像窗口函数的工作。假设我们将距离定义为:
from pyspark.sql.functions import acos, cos, sin, lit, toRadians
def dist(long_x, lat_x, long_y, lat_y):
return acos(
sin(toRadians(lat_x)) * sin(toRadians(lat_y)) +
cos(toRadians(lat_x)) * cos(toRadians(lat_y)) *
cos(toRadians(long_x) - toRadians(long_y))
) * lit(6371.0)
您可以将窗口定义为:
from pyspark.sql.window import Window
w = Window().partitionBy("User").orderBy("Timestamp")
并使用lag
计算连续观察之间的距离:
from pyspark.sql.functions import lag
df.withColumn("dist", dist(
"longitude", "latitude",
lag("longitude", 1).over(w), lag("latitude", 1).over(w)
).alias("dist"))
之后,您可以执行标准聚合。
答案 1 :(得分:2)
您可以使用SparkSQL中的Window函数计算两点之间的距离,然后将groupby与每个用户的距离相加。
以下是代码示例:https://gist.github.com/mr1azl/71f376e7efb6637a43b26a83e90d304a