基于条件合并两个DataFrame:保留共有的product_id/country组合
合并DataFrame并保留共同product_id/country组合的方法
原始DataFrame
df_products_cp
| product_id | version | country |
|---|---|---|
| 1111 | 2 | CO |
| 1111 | 2 | BR |
| 1111 | 2 | MX |
| 2222 | 2 | CO |
| 3333 | 2 | CO |
| 3333 | 2 | MX |
| 4444 | 2 | CO |
| 4444 | 2 | BR |
| 4444 | 2 | MX |
df_products_ec
| product_id | version | country |
|---|---|---|
| 1111 | 3 | CO |
| 1111 | 3 | MX |
| 2222 | 3 | CO |
| 4444 | 3 | CO |
| 4444 | 3 | BR |
需求说明
合并上述两个DataFrame,仅保留同时存在于两个DataFrame中的product_id/country组合的所有记录,目标结果如下:
目标DataFrame
| product_id | version | country |
|---|---|---|
| 1111 | 2 | CO |
| 1111 | 3 | CO |
| 1111 | 2 | MX |
| 1111 | 3 | MX |
| 2222 | 2 | CO |
| 2222 | 3 | CO |
| 4444 | 2 | CO |
| 4444 | 3 | CO |
| 4444 | 2 | BR |
| 4444 | 3 | BR |
解决方案
方法一:通过提取共同组合过滤后合并
先获取两个DataFrame共有的product_id+country组合,再分别过滤两个原始DataFrame,最后合并结果:
import pandas as pd # 提取共同的product_id/country组合 common_pairs = pd.merge( df_products_cp[['product_id', 'country']], df_products_ec[['product_id', 'country']], on=['product_id', 'country'], how='inner' ) # 过滤两个DataFrame,只保留共同组合的记录 filtered_cp = df_products_cp.merge(common_pairs, on=['product_id', 'country']) filtered_ec = df_products_ec.merge(common_pairs, on=['product_id', 'country']) # 合并并排序结果 result_df = pd.concat([filtered_cp, filtered_ec])\ .sort_values(by=['product_id', 'country', 'version'])\ .reset_index(drop=True)
方法二:用元组匹配直接过滤
将product_id和country转为元组,通过isin直接生成过滤掩码,效率更高:
import pandas as pd # 生成两个DataFrame的组合元组集合 cp_pairs = set(df_products_cp[['product_id', 'country']].apply(tuple, axis=1)) ec_pairs = set(df_products_ec[['product_id', 'country']].apply(tuple, axis=1)) # 获取交集组合 common_pairs = cp_pairs & ec_pairs # 过滤并合并结果 filtered_cp = df_products_cp[df_products_cp[['product_id', 'country']].apply(tuple, axis=1).isin(common_pairs)] filtered_ec = df_products_ec[df_products_ec[['product_id', 'country']].apply(tuple, axis=1).isin(common_pairs)] result_df = pd.concat([filtered_cp, filtered_ec])\ .sort_values(by=['product_id', 'country', 'version'])\ .reset_index(drop=True)
内容的提问来源于stack exchange,提问作者Alain
相关产品推荐
相关产品推荐

