为了账号安全,请及时绑定邮箱和手机立即绑定

如何在一个 pandas 数据帧列中搜索字符串作为另一个数据帧中的子字符串

如何在一个 pandas 数据帧列中搜索字符串作为另一个数据帧中的子字符串

PHP
白衣染霜花 2023-11-09 21:07:06
我有两个 pandas 数据框 df1 和 df2。我需要通过搜索 df2['B'] 来查看 df1['A'] 是否是 df2['B'] 的子字符串,在 df1 中创建一个新列,反之亦然。如果存在匹配,则返回 df1['B'] 中新列的 df2['A'] 值。以下是示例数据框df1  A                     B       8GSHDK1               ?  SDFAGHJFDJ GSHJGGFV  678HJDGGH  576GHJHJJKHJJH  YRYWEUIYWREdf2 A                B 1                GSHJGGFV 2                XXXYYYYY 3                8GSHDK1 TO BE DEL              在这种情况下合并不起作用,因为 df1['A'] 包含 df2['B'] 的子字符串或 df2['B'] 包含 df1['A'] 的子字符串。我在下面尝试过,但它运行了 7 到 8 小时。df1 有 25k 条记录,df2 有 720k 条记录df1['B']=df1['A'].apply(lambda x: df2[df2['B'].str.contains(x) | df2['B'].apply(lambda y : y in x)]['B'].any())任何帮助将非常感激。预期输出:df1  A                     B       8GSHDK1               8GSHDK1 TO BE DEL     SDFAGHJFDJ GSHJGGFV   GSHJGGFV  678HJDGGH             None  576GHJHJJKHJJH        None  YRYWEUIYWRE           None
查看完整描述

3 回答

?
DIEA

TA贡献1820条经验 获得超2个赞

我尝试使用LCS算法,我的逻辑是:

如果有两个字符串 A 和 B,其中一个可以是另一个的子串:

当且仅当,len(LCS(A,B))=min(len(A),len(B))

因此,我不是以两种方式匹配子字符串,而是以两种方式进行匹配。也许您需要稍微优化实现,但可以肯定它比双向搜索更快。

代码

%%time

from functools import lru_cache


@lru_cache(maxsize=2048)

def checkele(A, B):

    return ((len(B) >= len(A)) and (A in B)) or ((len(A) >= len(B)) and (B in A))


def check(A, Bs):

    for B in Bs:

        if checkele(*sorted([A, B])):

            return B

    return None

    

df1['B']=df1.A.apply( lambda x: check(x, df2.B))

df1


查看完整回答
反对 回复 2023-11-09
?
FFIVE

TA贡献1797条经验 获得超6个赞

您的代码中可以避免使用多个 apply 语句,并将其简化如下。这应该运行得更快。


df1['B'] = df1['A'].apply(lambda x: [y for y in df2['B'] if x.upper() in y.upper() or y.upper() in x.upper()]).str[0]

这打印:


                     A                  B

0              8GSHDK1  8GSHDK1 TO BE DEL

1  SDFAGHJFDJ GSHJGGFV           GSHJGGFV

2            678HJDGGH                NaN

3       576GHJHJJKHJJH                NaN

4          YRYWEUIYWRE                NaN


查看完整回答
反对 回复 2023-11-09
?
守着一只汪

TA贡献1872条经验 获得超3个赞

我认为您正在寻找的是pandas.concat。

df = pd.concat([df1['A'], df2['B']], axis=1)

之后您可以使用 apply ,其逻辑与您在问题中所写的类似。


查看完整回答
反对 回复 2023-11-09
  • 3 回答
  • 0 关注
  • 77 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信