Pandas:如何简洁实现两个DataFrame的笛卡尔积连接?
实现DataFrame组合式连接(笛卡尔积)的简洁方法
嘿,你要的其实就是两个DataFrame的笛卡尔积(也就是把每个DataFrame的每一行两两组合),不用再折腾繁琐的key合并啦,这里有几个更直观、更具Python风格的实现方式:
方法一:用pandas内置的交叉连接(推荐)
从pandas 1.2.0版本开始,merge方法新增了how='cross'参数,直接就能实现笛卡尔积,这是最简洁直观的方案:
import pandas as pd fred = pd.DataFrame({'A':[1., 4.],'B':[2., 5.], 'C':[3., 6.]}) jim = pd.DataFrame({'one':['a', 'c'],'two':['b', 'd']}) # 一行代码完成组合式连接 result = pd.merge(fred, jim, how='cross') print(result)
运行后输出:
A B C one two0 1.0 2.0 3.0 a b
1 1.0 2.0 3.0 c d
2 4.0 5.0 6.0 a b
3 4.0 5.0 6.0 c d
方法二:兼容旧版pandas的临时key方案
如果你还在使用低于1.2.0的pandas版本,可以通过添加一个临时的统一key来实现,比你之前的方法更简洁:
import pandas as pd fred = pd.DataFrame({'A':[1., 4.],'B':[2., 5.], 'C':[3., 6.]}) jim = pd.DataFrame({'one':['a', 'c'],'two':['b', 'd']}) # 添加临时key列,合并后删除 fred['temp_key'] = 1 jim['temp_key'] = 1 result = pd.merge(fred, jim, on='temp_key').drop('temp_key', axis=1) print(result)
方法三:用itertools.product实现纯Python风格的组合
如果你想更贴近Python原生的思路,可以用itertools.product生成所有行的笛卡尔积,再转为DataFrame:
import pandas as pd from itertools import product fred = pd.DataFrame({'A':[1., 4.],'B':[2., 5.], 'C':[3., 6.]}) jim = pd.DataFrame({'one':['a', 'c'],'two':['b', 'd']}) # 生成所有行的组合 row_combinations = product(fred.itertuples(index=False), jim.itertuples(index=False)) # 转换为DataFrame并设置列名 result = pd.DataFrame( [tuple(fred_row) + tuple(jim_row) for fred_row, jim_row in row_combinations], columns=list(fred.columns) + list(jim.columns) ) print(result)
各方法对比
- 方法一:最推荐,代码简洁易读,是pandas官方支持的标准方案,性能最优。
- 方法二:兼容旧版本,但需要额外处理临时列,略繁琐。
- 方法三:纯Python风格,适合理解笛卡尔积的底层逻辑,但大数据量下性能不如pandas内置的merge方法。
内容的提问来源于stack exchange,提问作者FredDref
相关产品推荐
相关产品推荐

