PySpark实现固定起始位置至末尾的子串列及报错解决
解决PySpark DataFrame子串提取报错并实现需求
报错原因
你遇到的TypeError: Column is not iterable,是因为substring函数的第三个参数不支持直接传入length("value")(Column类型)——该函数要求第三个参数为整数常量,或是通过SQL表达式来动态计算长度。
解决方案
方案1:修复原固定位置提取逻辑
用expr函数编写SQL风格的表达式,支持动态传入列长度,解决参数类型不匹配问题:
from pyspark.sql.functions import expr, length columns = ["key", "value"] data = [("key1", "09-2021_Books"), ("key2", "09-2021_Cds, value4"), ("key3", "09-2021_Computers"),] df = spark.createDataFrame(data).toDF(*columns) # 通过expr执行SQL语法的substring,支持动态计算长度 df.withColumn("items", expr("substring(value, 7, length(value))")).show()
方案2:更可靠的下划线后内容提取(推荐)
固定位置7的写法依赖于前缀字符串长度固定,一旦前缀格式变化就会失效。如果需求是提取下划线之后的所有内容,推荐用以下两种更灵活的方式:
方法A:split函数分割提取
from pyspark.sql.functions import split # 按下划线分割后取第二个元素(索引从0开始) df.withColumn("items", split("value", "_").getItem(1)).show()
方法B:substring_index函数提取
from pyspark.sql.functions import substring_index # 取最后一个下划线之后的内容,即使存在多个下划线也能正确提取 df.withColumn("items", substring_index("value", "_", -1)).show()
最终输出结果
三种方法执行后都会得到符合需求的结果:
+----+--------------------+-----------+ | key| value| items| +----+--------------------+-----------+ |key1| 09-2021_Books| Books| |key2|09-2021_Cds, value4|Cds, value4| |key3| 09-2021_Computers| Computers| +----+--------------------+-----------+
内容的提问来源于stack exchange,提问作者QueryQuasar
相关产品推荐
相关产品推荐

