PySpark DataFrame列应用自定义函数报IndexError的修复方法
报错原因
触发IndexError: string index out of range是因为自定义函数没有覆盖边界场景:
- 当传入的字符串是空值
''时,字符串长度为0,直接执行x[-1]取末尾字符会直接触发索引越界 - 当字符串内容全部由待删除的空格、逗号组成时(比如
' '、,,,、, ,这类值),循环会持续截断字符串直到长度为0,下一轮循环取x[-1]同样会触发越界 - 额外注意:如果
studios列存在null值,原函数还会抛出NoneType对象不支持索引的错误,也需要一并处理
修复方法
方法1:修改自定义函数逻辑,兼容边界场景
在取末尾字符前增加长度校验,同时处理null值,修改后的代码如下:
def remove_space_end(x): # 提前处理null和空字符串 if x is None or len(x) == 0: return x while True: # 每次截断后先判断长度,避免删到空后索引越界 if len(x) == 0: break if x[-1] == ' ' or x[-1] == ',': x = x[:-1] else: break return x # UDF调用逻辑无需改动 udf_remove = udf(lambda x:remove_space_end(x), StringType()) df = df.withColumn("studios",udf_remove(col("studios")))
方法2:使用Spark内置函数替代Python UDF(强烈推荐)
Python UDF需要在Executor端启动Python进程执行,性能远低于Spark原生内置函数。你的需求是移除字符串右端的空格和逗号,完全可以用内置的rtrim函数实现,逻辑完全等价,且自动兼容null、空字符串、全待删字符等边界场景,不会触发索引错误,代码更简洁:
from pyspark.sql.functions import col, rtrim # 第二个参数传入需要从右端移除的字符集合:空格、逗号 df = df.withColumn("studios", rtrim(col("studios"), " ,"))
内容的提问来源于stack exchange,提问作者Lorenzo Maggio
相关产品推荐
相关产品推荐

