猿问

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

我有两个 pandas 数据框 df1 和 df2。我需要通过搜索 df2['B'] 来查看 df1['A'] 是否是 df2['B'] 的子字符串,在 df1 中创建一个新列,反之亦然。如果存在匹配,则返回 df1['B'] 中新列的 df2['A'] 值。


以下是示例数据框


df1


  A                     B     

  8GSHDK1               ?

  SDFAGHJFDJ GSHJGGFV

  678HJDGGH

  576GHJHJJKHJJH

  YRYWEUIYWRE

df2


 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


白衣染霜花
浏览 119回答 3
3回答

DIEA

我尝试使用LCS算法,我的逻辑是:如果有两个字符串 A 和 B,其中一个可以是另一个的子串:当且仅当,len(LCS(A,B))=min(len(A),len(B))因此,我不是以两种方式匹配子字符串,而是以两种方式进行匹配。也许您需要稍微优化实现,但可以肯定它比双向搜索更快。代码%%timefrom 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

FFIVE

您的代码中可以避免使用多个 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                  B0              8GSHDK1  8GSHDK1 TO BE DEL1  SDFAGHJFDJ GSHJGGFV           GSHJGGFV2            678HJDGGH                NaN3       576GHJHJJKHJJH                NaN4          YRYWEUIYWRE                NaN

守着一只汪

我认为您正在寻找的是pandas.concat。df = pd.concat([df1['A'], df2['B']], axis=1)之后您可以使用 apply ,其逻辑与您在问题中所写的类似。
随时随地看视频慕课网APP
我要回答