如何在Polars中先分组再执行交叉连接并计算唯一组合差价?
Polars按分组实现组内交叉连接并计算唯一组合差异
直接上可运行的代码,完美实现按garment分组、组内交叉连接、保留唯一组合并计算价格差的需求:
import polars as pl df = pl.DataFrame( { "garment": ["tshirt", "tshirt", "tshirt", "pants", "pants", "pants", "socks", "socks", "socks"], "color": ["red", "blue", "green", "yellow", "orange", "purple", "black", "white", "grey"], "price": [100, 50, 75, 101, 51, 69, 99, 44, 32] } ) result = df.group_by("garment").map_groups( lambda group: group.join(group, how="cross") # 过滤自连接+保留唯一组合:仅保留字典序左小右大的组合 .filter(pl.col("color") < pl.col("color_right")) .with_columns( pl.col("price").sub(pl.col("price_right")).abs().alias("price_difference") ) # 可选:调整列顺序让输出更清晰 .select("garment", "color", "color_right", "price", "price_right", "price_difference") ) print(result)
关键逻辑拆解
分组批量处理:
用group_by("garment").map_groups()自动遍历所有服装分组,每个分组独立执行交叉连接逻辑,不用手动逐个过滤分组。唯一组合过滤:
把原逻辑的color != color_right替换为color < color_right,利用字符串的字典序特性:- 自动排除自连接(同一个color不可能小于自身)
- 仅保留单向组合(比如只留
orange-yellow,不会出现yellow-orange)
价格差计算:
用Polars的向量化函数sub()替代减法运算符,配合abs()计算绝对值差,性能比循环更优。
额外说明
- 如果你的
color字段不是字符串(比如数字、枚举),只要类型支持比较运算,color < color_right的逻辑完全通用; - 交叉连接会产生
n*(n-1)/2条数据(n为分组内行数),大分组场景下注意内存占用; - 可根据需求调整
select()里的列顺序,或者添加/删除字段。
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

