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

在Pandas中对齐两列字符串(递归合并直至匹配)

问题场景

现有如下Pandas DataFrame:

import pandas as pd
df = pd.DataFrame(data={'col1': ["Sun", "Sea:", "SARS-COV-2", "Hong-Kong", "Fish", "NaN", "NaN", "NaN", "NaN", "NaN", "NaN", "NaN"],
                        'col2': ["Sun", "Sea", ":", "SARS", "-", "COV", "-", "2", 'Hong', '-', 'Kong', 'Fish'],
                        'col3': ["H", "Q", "S", "X", "Y", "Z", "L", "M", 'A', 'B', 'C', 'O']})

其中col1包含完整目标字符串和NaN值,col2是拆分后的字符串片段。需要合并col2的片段,使其与col1的非NaN值匹配,同时保留匹配时对应的第一个col3值,最终得到目标DataFrame:

df2 = pd.DataFrame(data={'col1': ["Sun","Sea:", "SARS-COV-2", "Hong-Kong", "Fish"],
                        'col2': ["Sun", "Sea:", "SARS-COV-2", "Hong-Kong", "Fish"],
                        'col3': ["H", "Q", "X",  "A",'O']})

尝试嵌套循环实现但逻辑混乱,求可行方案。

解决方案

可以通过追踪合并进度+匹配目标字符串或者分组聚合的方式实现,两种方案都能避免混乱的嵌套循环:

方案一:逐行遍历合并

  • 提取col1中的目标字符串,过滤掉NaN值:
    targets = df[df['col1'] != 'NaN']['col1'].tolist()
    
  • 初始化合并缓存、结果列表和目标索引:
    current_merge = ""
    result = []
    target_idx = 0
    
  • 遍历col2片段,逐步拼接直到匹配当前目标:
    for seg, c3 in zip(df['col2'], df['col3']):
        current_merge += seg
        if current_merge == targets[target_idx]:
            # 找到匹配时,取该目标对应第一个片段的col3值
            first_seg = targets[target_idx][0] if len(targets[target_idx]) == 1 else targets[target_idx].split(sep=None, maxsplit=1)[0]
            first_c3 = df.loc[df['col2'] == first_seg, 'col3'].iloc[0]
            result.append({
                'col1': targets[target_idx],
                'col2': current_merge,
                'col3': first_c3
            })
            # 重置缓存,切换到下一个目标
            current_merge = ""
            target_idx += 1
            if target_idx >= len(targets):
                break
    
  • 转换为目标DataFrame:
    df2 = pd.DataFrame(result)
    

方案二:分组聚合(更高效)

利用Pandas的分组功能,通过目标位置标记分组,直接完成合并和取值:

  • 标记分组:用col1的非NaN值作为分组标记点,生成连续分组ID:
    df['group_id'] = df['col1'].ne('NaN').cumsum()
    
  • 分组聚合:合并每组的col2片段,同时取每组第一个col3值,提取col1的目标字符串:
    df2 = df.groupby('group_id').agg(
        col1=('col1', lambda x: x[x != 'NaN'].iloc[0]),
        col2=('col2', ''.join),
        col3=('col3', 'first')
    ).reset_index(drop=True)
    

两种方案运行后得到的df2都完全符合需求,方案二更适合大数据量场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:52:33