2015-08-15 6 views
4

Я новичок в dataframes с искрой, и это иногда странно. Предположим, у меня есть dataframe, содержащий Logs с координатами широты и долготы.Geo Filter with Spark DataFrame

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 и долгота находятся в определенном радиусе от заранее определенного местоположения.

Теперь, как фильтровать точку Log, которая не удовлетворяет внутри. Я попытался

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

Но это не подразумевает Дубль и вместо этого он возвращает столбец как тип. Как я могу заставить это работать? Документы в искровом месте немного упрощены, я уверен, что чего-то не хватает.

Благодарим за помощь.

ответ

6

Вообще говоря, вам нужно как минимум две вещи, чтобы заставить его работать. Во-первых, вы должны создать UDF оберточной within:

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

val withinUDF = udf(within _) 

Далее, когда UDF называется, радиус должен быть отмечен как буквальный:

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

Поскольку не каждый тип может быть передан этот путь и создание оберток и вызова lit довольно утомительно вы можете предпочесть выделки:

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

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

Это является удивительным, прекрасно работает. Мне не хватало буквальной части. Я обязательно переписал код с карри. Только что начал писать Скала. Спасибо. – Eriksen