PySpark按name和id取最大date数据报错:Column不可迭代
PySpark 获取每个name/id组合对应最大date的完整行数据
问题根源
你最初用groupBy('name','id','tfh','tfc')聚合max(date)的方式无效,是因为tfh和tfc会被当作分组维度——只要这两个字段值不同,就会生成独立分组,无法得到每个name/id组合的唯一最大date记录。
解决方案1:窗口函数法(最简洁高效)
用row_number()窗口函数给每个name/id分组的行按date降序编号,取编号为1的行即可拿到对应最大date的完整数据:
from pyspark.sql import Window from pyspark.sql.functions import row_number, desc # 定义窗口规则:按name、id分组,date降序排序 window_spec = Window.partitionBy("name", "id").orderBy(desc("date")) # 添加行号并筛选目标行 result_df = df.withColumn("row_num", row_number().over(window_spec)) \ .filter("row_num = 1") \ .drop("row_num")
这种方法无需额外关联,直接在原数据集上处理,避免关联时的语法错误。
解决方案2:关联法(修正你之前的报错)
你之前遇到TypeError: Column is not iterable,大概率是关联时的on参数写法错误。正确步骤是先聚合出每个name/id的最大date,再通过精准条件关联原表:
from pyspark.sql.functions import max # 第一步:聚合得到每个name/id对应的最大date max_date_df = df.groupBy("name", "id").agg(max("date").alias("max_date")) # 第二步:用布尔条件关联原表,匹配name、id、date等于max_date的行 result_df = df.join( max_date_df, (df.name == max_date_df.name) & (df.id == max_date_df.id) & (df.date == max_date_df.max_date), how="inner" ).drop(max_date_df.name, max_date_df.id) # 移除重复的分组列
注意:不要在on的列表参数中混入Column对象(比如直接写["name","id", df.date == max_date_df.max_date]),必须用&连接布尔条件,或者将同名列放在列表,单独处理date的匹配。
内容的提问来源于stack exchange,提问作者Turvy
相关产品推荐
相关产品推荐

