
本文介绍如何在 pyspark dataframe 中对无序水果组合(如 apple-orange-cherry 与 orange-apple-cherry)进行逻辑去重,并按组合计数降序保留前 n 行。核心在于标准化组合表示、窗口去重与全局排序截断。
本文介绍如何在 pyspark dataframe 中对无序水果组合(如 apple-orange-cherry 与 orange-apple-cherry)进行逻辑去重,并按组合计数降序保留前 n 行。核心在于标准化组合表示、窗口去重与全局排序截断。
在实际数据分析中,常遇到“顺序无关但语义相同”的集合型字段(例如多标签、物品组合、特征组等)。原始数据可能因录入顺序不同导致同一组合被多次记录(如 ['apple','orange','cherry'] 和 ['orange','apple','cherry']),但它们代表完全相同的组合,应视为重复项。PySpark 本身不直接支持集合去重,需通过标准化 + 窗口函数实现。
关键思路分三步:
- 标准化组合表达:将多列水果字段合并为一个有序数组,确保相同元素的不同排列映射为唯一标识;
-
组内去重:使用
row_number()窗口函数,按标准化后的组合分组,并在组内按count降序排序,只保留每组首行(rank == 1); -
全局截取 Top-N:对去重后结果按
count降序排序,并用limit(N)获取前 N 行。
以下为完整可运行代码(基于 Spark 3.1+,支持 array_sort 和 array 函数):
from pyspark.sql import functions as F
from pyspark.sql.window import Window
# 假设 df 是你的原始 PySpark DataFrame(注意:非 Pandas!)
# 示例构建(仅用于演示,生产环境请替换为真实读取逻辑)
df = spark.createDataFrame([
("apple", "orange", "cherry", 10),
("orange", "apple", "cherry", 10),
("banana", "cherry", "apple", 5),
("cherry", "apple", "orange", 3)
], ["first_fruit", "second_fruit", "third_fruit", "count"])
# 步骤:标准化组合 → 分组编号 → 过滤首行 → 全局排序 → 截取 Top 2
result_df = (
df
.withColumn(
"combo_sorted",
F.array_sort(F.array("first_fruit", "second_fruit", "third_fruit"))
)
.withColumn(
"rank_in_combo",
F.row_number().over(
Window.partitionBy("combo_sorted")
.orderBy(F.desc("count")) # 相同组合内按 count 降序,确保高计数优先保留
)
)
.filter(F.col("rank_in_combo") == 1)
.drop("combo_sorted", "rank_in_combo")
.orderBy(F.desc("count"))
.limit(2)
)
result_df.show()
✅ 输出示例:
+-----------+------------+------------+-----+ |first_fruit|second_fruit|third_fruit |count| +-----------+------------+------------+-----+ | apple| orange| cherry| 10| | banana| cherry| apple| 5| +-----------+------------+------------+-----+
⚠️ 注意事项:
-
array_sort()要求 Spark ≥ 3.1;若使用旧版本,可用 UDF 手动实现字符串拼接(如concat_ws("_", sort_array(array(...)))),但性能略低; -
row_number()必须指定orderBy子句(即使count相同),否则报错;此处按count DESC保证高频组合优先进入结果; - 若存在
NULL值,array_sort会将其排至数组开头,建议提前用coalesce()或fillna()处理缺失; - 本方案天然支持任意数量水果列(只需扩展
F.array(...)中的字段列表),无需硬编码列名逻辑。
通过该方法,你不仅能精准消除语义重复,还能灵活控制最终输出规模,适用于推荐系统组合分析、购物篮挖掘、A/B 测试多维分组等典型场景。










