You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用纯Pandas高效创建关联购买商品的查找表?

用纯Pandas高效实现商品关联购买查找表

你的暴力循环方法虽然直观,但在数据量较大时效率会很低——iterrows()本身就不是高性能的遍历方式,嵌套循环更是会让时间复杂度飙升。下面提供两种纯Pandas的高效实现方案,性能和代码优雅度都更优:

方案一:基于自连接的纯Pandas实现

这种方法利用Pandas的merge操作完成同一发票内的商品配对,完全避免Python层面的循环:

import pandas as pd

df = pd.DataFrame({
    "Invoice": [1, 1, 2, 3, 4, 4, 4, 5, 5], 
    "Item": ["Apple", "Pear", "Banana", "Apple", "Apple", "Orange", "Pear", "Apple", "Orange"]
})

# 1. 添加临时列用于按发票自连接
df_temp = df.assign(temp=df["Invoice"])

# 2. 按发票字段自连接,得到同一发票下的所有商品组合
joined_df = df_temp.merge(df_temp, on="temp", suffixes=("_key", "_value"))

# 3. 过滤掉商品自身配对的行,整理成目标格式
lookup_table = (
    joined_df[joined_df["Item_key"] != joined_df["Item_value"]]
    .rename(columns={"Item_key": "key", "Item_value": "value"})
    [["key", "value"]]
    .reset_index(drop=True)
)

print(lookup_table)

方案二:结合分组与组合生成(需itertools辅助)

如果想更清晰地控制商品配对逻辑,可以先按发票分组,再生成每组内的商品组合,最后展开结果:

import pandas as pd
from itertools import combinations

df = pd.DataFrame({
    "Invoice": [1, 1, 2, 3, 4, 4, 4, 5, 5], 
    "Item": ["Apple", "Pear", "Banana", "Apple", "Apple", "Orange", "Pear", "Apple", "Orange"]
})

# 1. 按发票分组,生成每组内的无序商品两两组合
grouped_pairs = df.groupby("Invoice")["Item"].apply(lambda x: list(combinations(x, 2)))

# 2. 展开所有组合并转为key-value格式
lookup_table = grouped_pairs.explode().apply(pd.Series).rename(columns={0: "key", 1: "value"})

# 3. 添加反向配对(和原代码逻辑一致,保留双向关联)
reverse_pairs = lookup_table.rename(columns={"key": "value", "value": "key"})
lookup_table = pd.concat([lookup_table, reverse_pairs]).reset_index(drop=True)

print(lookup_table)

为什么这两种方法更优?

  • 性能提升:Pandas的merge和分组操作都是基于C语言实现的内部优化,比Python循环快几个数量级,数据量越大优势越明显。
  • 代码简洁:用链式调用和内置操作替代嵌套循环,逻辑更清晰,可读性更强。
  • 可扩展性:后续如果需要调整配对规则(比如只保留唯一配对、统计关联次数),可以直接在现有代码上修改,无需重构循环逻辑。

内容的提问来源于stack exchange,提问作者DanneP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 13:54:58