Pyspark 如何高效转换多列为数值类型以正常运行haversine方法?
PySpark Haversine 运行报错修复方案
原代码核心问题
- 重复给
DISTANCE列赋值的4次withColumn操作完全冗余,每次都会覆盖上一次的结果,没有实际完成4个经纬度字段的类型转换 - 直接传入字符串列名给
haversine时,若原始经纬度列为字符串类型,会直接触发类型不匹配报错 - 用
IntegerType转换经纬度会直接截断小数部分,导致距离计算出现严重精度偏差,应替换为浮点类型
符合要求的实现代码
from pyspark.sql.functions import col from pyspark.sql.types import DoubleType q9 = q4.withColumn( "distance", haversine( col("LOCLONG").cast(DoubleType()), col("LOCLAT").cast(DoubleType()), col("LOCLONG2").cast(DoubleType()), col("LOCLAT2").cast(DoubleType()) ) )
如果不需要单独导入类型类,也可以直接用字符串指定类型,效果一致:
q9 = q4.withColumn( "distance", haversine( col("LOCLONG").cast("double"), col("LOCLAT").cast("double"), col("LOCLONG2").cast("double"), col("LOCLAT2").cast("double") ) )
需求匹配说明
- 高效类型转换:类型转换和距离计算在同一个计算逻辑内完成,无需生成多个冗余的中间DataFrame,Spark Catalyst优化器可直接对该逻辑做执行优化,效率更高
- 仅一次withColumn:整个操作只调用一次
withColumn,没有生成无用的中间数据集 - 参数类型合规:所有传入
haversine的参数都提前转换为双精度数值类型,避免了字符串类型传入的报错问题
如果haversine是自定义注册的UDF,只需确保UDF定义的输入参数类型为浮点/双精度数值类型,和上述转换的类型匹配即可。
内容的提问来源于stack exchange,提问作者Ana
相关产品推荐
相关产品推荐

