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

如何基于单个坐标元组是否存在于元组列表中来合并两个Pandas DataFrame?

解决思路:基于「坐标元组是否在列表中」合并Pandas DataFrame

当然有可行的思路啦!我来给你分几种情况讲解,从简单直观到高效优化的方案都有,你可以根据自己的数据量来选~

首先先构造个示例数据,方便你理解场景:

import pandas as pd

# 示例DataFrame1:包含坐标元组列表
df1 = pd.DataFrame({
    'id': [1, 2, 3],
    'coord_list': [[(1,2), (3,4)], [(5,6)], [(7,8), (9,10), (1,2)]]
})

# 示例DataFrame2:包含单个坐标元组
df2 = pd.DataFrame({
    'value': ['A', 'B', 'C'],
    'single_coord': [(1,2), (5,6), (11,12)]
})

方法1:简单直观的「展开+合并」法(适合小数据量)

这个方法逻辑最清晰,适合数据规模不大的场景:

  1. 把df1中存储坐标列表的列展开,让每个坐标元组单独占一行
  2. 用展开后的坐标列和df2的单个坐标列做合并
  3. (可选)如果需要还原成原df1的结构,再按原id聚合

代码实现:

# 1. 展开df1的坐标列表,并重命名列名和df2对齐
df1_exploded = df1.explode('coord_list').rename(columns={'coord_list': 'single_coord'})

# 2. 按坐标元组合并两个DataFrame,这里用left_join保留df1所有行
merged = pd.merge(df1_exploded, df2, on='single_coord', how='left')

# 3. (可选)将同一id的匹配结果聚合回去,还原原结构
result = merged.groupby('id').agg({
    'coord_list': 'first',  # 保留原来的坐标列表
    'value': list  # 把匹配到的value收集成列表
}).reset_index()

方法2:预构建映射字典(适合中等数据量)

如果df1的坐标列表很长,或者数据量较大,先构建「坐标元组→对应df1行id」的映射字典,能大幅提升匹配效率:

  1. 遍历df1,把每个坐标元组和对应的id存进字典
  2. 用字典快速查找df2每个坐标对应的id
  3. 展开匹配结果后再和df1合并

代码实现:

# 1. 构建坐标到id的映射字典
coord_to_ids = {}
for idx, row in df1.iterrows():
    for coord in row['coord_list']:
        if coord not in coord_to_ids:
            coord_to_ids[coord] = []
        coord_to_ids[coord].append(row['id'])

# 2. 给df2添加匹配到的id列表,没有匹配的填充空列表
df2['matched_ids'] = df2['single_coord'].map(coord_to_ids).fillna([])

# 3. 展开id列表并和df1合并
df2_exploded = df2.explode('matched_ids').rename(columns={'matched_ids': 'id'})
result = pd.merge(df1, df2_exploded, on='id', how='left')

方法3:用集合优化查找速度(适合列表很长的场景)

当df1的坐标列表特别长时,用列表做in判断会很慢,换成集合能把查找时间从O(n)降到O(1):

# 1. 把df1的坐标列表转换成集合,加快查找
df1['coord_set'] = df1['coord_list'].apply(set)

# 2. 定义函数,查找单个坐标在df1中匹配的id
def find_matching_ids(coord):
    return df1[df1['coord_set'].apply(lambda x: coord in x)]['id'].tolist()

# 3. 给df2添加匹配id列表,后续展开合并和方法2一致
df2['matched_ids'] = df2['single_coord'].apply(find_matching_ids)
df2_exploded = df2.explode('matched_ids')
result = pd.merge(df1, df2_exploded, on='id', how='left')

方法4:拆分坐标为数值列(适合超大数据量)

如果你的数据量达到百万级以上,上面的方法可能还是不够快,可以把坐标元组拆成单独的x、y数值列,利用Pandas对数值列的高效合并能力:

# 1. 展开df1的坐标列表,并拆分元组为x、y列
df1_exploded = df1.explode('coord_list')
df1_exploded[['x', 'y']] = pd.DataFrame(df1_exploded['coord_list'].tolist(), index=df1_exploded.index)

# 2. 拆分df2的单个坐标为x、y列
df2[['x', 'y']] = pd.DataFrame(df2['single_coord'].tolist(), index=df2.index)

# 3. 用x、y列合并,效率比直接合并元组更高
merged = pd.merge(df1_exploded, df2, on=['x', 'y'], how='left')

# 4. (可选)聚合回原结构
result = merged.groupby('id').agg({
    'coord_list': 'first',
    'value': list
}).reset_index()

注意事项

  • 坐标元组是可哈希的,所以可以直接作为字典键、集合元素,不用担心报错
  • 合并时的how参数可以根据需求调整:left保留df1所有行,right保留df2所有行,inner只保留双方匹配的行
  • 如果不需要还原原结构,直接使用展开后的合并结果即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 16:37:38