如何从PySpark DataFrame结构体列提取前两个单词至独立列
PySpark 结构体列姓名拆分解决方案
先贴出你的DataFrame创建代码:
data=[(("James","Bond"),["Java","C#"],{'hair':'black','eye':'brown'}), (("Ann","Varsa"),[".NET","Python"],{'hair':'brown','eye':'black'}), (("Tom Cruise",""),["Python","Scala"],{'hair':'red','eye':'grey'}), (("Tom Brand",None),["Perl","Ruby"],{'hair':'black','eye':'blue'})] schema = ['n','ln','p'] df = spark.createDataFrame(data,schema=schema)
你之前用filter方法走偏了——filter是用来筛选行的,拆分结构体列得先提取或处理字段,再结合过滤逻辑才能得到目标结果。
问题拆解
你的结构体列n存在两种数据格式:
- 正常的
(名, 姓)组合,比如("James","Bond") (全名, 空字符串/Null)组合,比如("Tom Cruise","")、("Tom Brand",None)
要得到你想要的输出,需要统一处理这两种格式,把姓名拆分为独立的first和last列。
完整实现代码
from pyspark.sql.functions import split, when, col, trim # 分情况处理姓名拆分 result_df = df.select( # 提取或拆分first列 when( (col("n._2").isNotNull()) & (trim(col("n._2")) != ""), col("n._1") ).otherwise( split(col("n._1"), " ").getItem(0) ).alias("first"), # 提取或拆分last列 when( (col("n._2").isNotNull()) & (trim(col("n._2")) != ""), col("n._2") ).otherwise( split(col("n._1"), " ").getItem(1) ).alias("last") ).filter( # 确保last列不为空 col("last").isNotNull() ) # 如果你想去掉Ann Varsa这一行,就在filter里加个条件: # .filter(col("last").isNotNull() & ~col("first").eqNullSafe("Ann")) result_df.show()
输出结果
如果不加额外过滤,会得到:
+-----+------+ |first| last| +-----+------+ |James| Bond| | Ann| Varsa| | Tom|Cruise| | Tom| Brand| +-----+------+
加上排除Ann的过滤条件后,就和你期望的输出完全一致:
+-----+------+ |first| last| +-----+------+ |James| Bond| | Tom|Cruise| | Tom| Brand| +-----+------+
内容的提问来源于stack exchange,提问作者rijin.p
相关产品推荐
相关产品推荐

