使用Spark DataFrame进行地理过滤

时间:2015-08-15 08:44:11

标签: scala apache-spark dataframe apache-spark-sql

我对带有火花的数据框架感到陌生,而且它有时很奇怪。 我们假设我的数据框包含带有纬度和经度坐标的日志。

 LogsDataFrame.printSchema :
 root
 |-- lat: double (nullable = false)
 |-- lon: double (nullable = false)
 |-- imp: string (nullable = false)
 |-- log_date: string (nullable = true)
 |-- pubuid: string (nullable = true)

另一方面,我有一个简单的方法

within(lat : Double, long : Double, radius : Double) : Boolean

表示lat和lon是否在预定义位置的某个半径内。

现在,如何过滤内部不满足的Log Log。我试过了

logsDataFrame.filter(within(logsDF("lat"), logsDF("lon"), RADIUS)

但是它没有推断出Double而是它将Column作为类型返回。 我怎样才能使这个工作? 火花网站上的文档有点简单,我确定我错过了什么。

感谢您的帮助。

1 个答案:

答案 0 :(得分:6)

一般来说,至少需要两件事才能让它发挥作用。首先,您必须创建UDF包裹within

import org.apache.spark.sql.functions.{udf, lit}

val withinUDF = udf(within _)

接下来,当调用UDF时,radius应标记为文字:

df.where(withinUDF($"lat", $"long", lit(RADIUS)))

因为并非所有类型都可以通过这种方式传递并且创建包装器并调用lit相当繁琐,所以您可能更喜欢使用currying:

def within(radius: Double) = udf((lat: Double, long: Double) => ???)

df.where(within(RADIUS)($"lat", $"long"))