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

如何在Pandas中提取两列字符串差异并生成新列?

在Pandas数据框中生成字符串差异对比列

需求与示例

你需要在Pandas数据框中新增一列colC,用来展示colA和colB两列字符串的差异。

原始数据

colAcolB
this is testthis is a testing

期望结果

colAcolBcolC
this is testthis is a testingthis is a ____

现有代码

你已经实现了字符串差异对比的函数,但不清楚如何将其应用到数据框的列上:

import re
import difflib

def tokenize(s):
    return re.split('\s+', s)

def untokenize(ts):
    return ' '.join(ts)

def equalize(s1, s2):
    l1 = tokenize(s1)
    l2 = tokenize(s2)
    res1 = []
    res2 = []
    prev = difflib.Match(0,0,0)
    for match in difflib.SequenceMatcher(a=l1, b=l2).get_matching_blocks():
        if (prev.a + prev.size != match.a):
            for i in range(prev.a + prev.size, match.a):
                res2 += ['_' * len(l1[i])]
            res1 += l1[prev.a + prev.size:match.a]
        if (prev.b + prev.size != match.b):
            for i in range(prev.b + prev.size, match.b):
                res1 += ['_' * len(l2[i])]
            res2 += l2[prev.b + prev.size:match.b]
        res1 += l1[match.a:match.a+match.size]
        res2 += l2[match.b:match.b+match.size]
        prev = match
    return untokenize(res1), untokenize(res2)

该函数对示例字符串的输出为:('this is a test _______', 'this is a ____ testing')。


解决方案

1. 基础应用:用apply逐行处理

通过pandas.DataFrame.apply()可以对数据框的每一行调用equalize函数,提取需要的结果生成colC。

步骤:

首先导入pandas并构造示例数据框:

import pandas as pd

# 构造示例数据框
df = pd.DataFrame({
    'colA': ['this is test'],
    'colB': ['this is a testing']
})

然后可以选择两种方式生成colC:

# 方式一:自定义单行处理函数,更易维护
def generate_colC(row):
    # 调用equalize函数获取对比结果
    res_a, res_b = equalize(row['colA'], row['colB'])
    # 根据期望结果,移除res_b末尾的" testing"部分
    return res_b.replace(" testing", "")

df['colC'] = df.apply(generate_colC, axis=1)
# 方式二:用lambda简化代码,适合简单场景
df['colC'] = df.apply(lambda row: equalize(row['colA'], row['colB'])[1].replace(" testing", ""), axis=1)

运行后,数据框会生成符合期望的colC列。

2. 空值与异常处理

如果数据框中存在空值,建议在equalize函数中添加判断逻辑,避免报错:

def equalize(s1, s2):
    # 处理空值情况
    if pd.isna(s1) or pd.isna(s2):
        return "", ""
    
    l1 = tokenize(s1)
    l2 = tokenize(s2)
    res1 = []
    res2 = []
    prev = difflib.Match(0,0,0)
    for match in difflib.SequenceMatcher(a=l1, b=l2).get_matching_blocks():
        if (prev.a + prev.size != match.a):
            for i in range(prev.a + prev.size, match.a):
                res2 += ['_' * len(l1[i])]
            res1 += l1[prev.a + prev.size:match.a]
        if (prev.b + prev.size != match.b):
            for i in range(prev.b + prev.size, match.b):
                res1 += ['_' * len(l2[i])]
            res2 += l2[prev.b + prev.size:match.b]
        res1 += l1[match.a:match.a+match.size]
        res2 += l2[match.b:match.b+match.size]
        prev = match
    return untokenize(res1), untokenize(res2)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 01:17:55