我是spark和python的新手。任何帮助赞赏。
我正在使用UDF并使用US zipcd,纬度和经度
创建了一个火花数据帧UDF:
import math
def distance(origin, destination):
lat1, lon1 = origin
lat2, lon2 = destination
radius = 6371 # km
dlat = math.radians(lat2-lat1)
dlon = math.radians(lon2-lon1)
a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(lat1)) \
* math.cos(math.radians(lat2)) * math.sin(dlon/2) * math.sin(dlon/2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
d = radius * c
return d
示例UDF输出:
distance((101,121),(-121,-212))
15447.812243421227
数据帧:
zip=spark.read.option("sep", ",").csv('wasb://hdiazurepoc@dsazurepoc.blob.core.windows.net/main/zip.txt')
zip1=zip.select(zip._c0,zip._c1.cast("Double"),zip._c2.cast("Double"))
zip1数据示例:
zip1.first()
行(_c0 = u' 00601',_ c1 = 18.180555,_c2 = -66.749961)
现在我试图将经度和经度从df zip1传递到udf距离,但是我得到的错误就像"需要一个浮点数"。 我相信udf没有从df字段获取数据,而是将df列作为常量值读取;因此我得到了错误。
z=zip1.select(distance((zip1._c1,100.23),(zip1._c2,-99.21)))
追踪(最近的呼叫最后):
文件"",第1行,在
文件"",第5行,距离
TypeError:需要浮点数
请告诉我将df字段传递给udf的正确方法。
答案 0 :(得分:6)
我不太确定你拥有的数据模式是什么。
但下面的示例是使用udf
来获得示例答案的正确方法。
from pyspark.sql.functions import *
from pyspark.sql.types import *
import math
def distance(origin, destination):
lat1, lon1 = origin
lat2, lon2 = destination
radius = 6371 # km
dlat = math.radians(lat2-lat1)
dlon = math.radians(lon2-lon1)
a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(lat1)) \
* math.cos(math.radians(lat2)) * math.sin(dlon/2) * math.sin(dlon/2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
d = radius * c
return d
df = spark.createDataFrame([([101, 121], [-121, -212])], ["origin", "destination"])
filter_udf = udf(distance, DoubleType())
df.withColumn("distance", filter_udf(df.origin, df.destination))
+----------+------------+------------------+
| origin| destination| distance|
+----------+------------+------------------+
|[101, 121]|[-121, -212]|15447.812243421227|
+----------+------------+------------------+