如何在大型DataFrame中不使用笛卡尔积查找同ID跨公司数据对
大表匹配同ID跨公司数据对的优化方案
你原来的笛卡尔积实现会生成200000 * 200000 = 400亿行中间数据,内存占用会达到几十上百GB,普通消费级硬件根本扛不住,核心问题是做了大量无意义的跨ID拼接,完全可以避免。
方案1:按ID做内连接(最易实现,兼容有序/无序对需求)
核心思路是只拼接ID相同的行,从根源上砍掉跨ID的无效计算,中间数据量会根据ID的重复度骤降到几十万到几百万条,普通笔记本就能轻松跑。
import pandas as pd # 按ID做内连接,仅合并ID相同的行,自动跳过所有ID不匹配的组合 df_merged = pd.merge( df, df, on="id", how="inner", suffixes=("_x", "_y") # 自动给重名的company列加后缀,匹配你要的输出格式 ) # 过滤同公司的无效配对 # 如果需要保留(A,B)、(B,A)这类双向有序对,用 != 判断 result = df_merged[df_merged["company_x"] != df_merged["company_y"]].copy() # 如果只需要不重复的无序对(和你给出的示例输出一致,没有反向重复),把判断条件改成 < 即可 # result = df_merged[df_merged["company_x"] < df_merged["company_y"]].copy() # 补全示例要求的id_x、id_y列(两列值完全等于匹配的ID) result["id_x"] = result["id"] result["id_y"] = result["id"] # 调整列顺序和示例一致 result = result[["company_x", "company_y", "id_x", "id_y"]]
方案2:分组生成组合(性能最优,适合仅需无序对的场景)
如果你的需求和示例一致,只需要不重复的跨公司无序对,这个方案内存占用最低、速度最快:核心是先按ID分组,直接为每个ID下的不同公司生成两两组合,完全跳过只有1家公司的无效ID,没有冗余的拼接计算。
import pandas as pd from itertools import combinations result_records = [] # 按ID分组遍历,关闭排序提升速度 for target_id, group in df.groupby("id", sort=False): # 取当前ID下所有不重复的公司 company_list = group["company"].unique() # 只有1家公司的ID不可能产生跨公司对,直接跳过 if len(company_list) < 2: continue # 生成两两不重复的公司组合,自动避免自身配对、反向重复 for comp_x, comp_y in combinations(company_list, 2): result_records.append({ "company_x": comp_x, "company_y": comp_y, "id_x": target_id, "id_y": target_id }) # 直接转成目标格式的DataFrame result = pd.DataFrame(result_records)
方案选择参考
- 如果你需要保留所有有序配对(比如既要A-B、也要B-A),选方案1,过滤时用
!=判断即可 - 如果你只需要示例里的无重复无序配对,优先选方案2,20万行数据通常几秒就能跑完,内存占用不到100MB
内容的提问来源于stack exchange,提问作者ZhaiShang
相关产品推荐
相关产品推荐

