如何在一个熊猫数据框列中搜索字符串作为另一数据框中的子字符串

时间:2020-10-14 07:42:04

标签: python pandas

我有两个熊猫数据帧df1和df2。我需要通过搜索df2 ['B']在df1中创建新列,以查看df1 ['A']是df2 ['B']的子字符串,反之亦然。如果存在匹配项,则返回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有25,000条记录,df2有72万条记录

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 个答案:

答案 0 :(得分:0)

可以在您的代码中避免使用多个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

答案 1 :(得分:0)

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

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

iff, 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

答案 2 :(得分:-2)

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

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

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