【问题标题】:How to search a string in one pandas dataframe column as a substring in another dataframe如何在一个熊猫数据框列中搜索字符串作为另一个数据框中的子字符串
【发布时间】:2021-01-28 14:08:25
【问题描述】:

我有两个熊猫数据框 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 有 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

【问题讨论】:

  • 我试过了,但性能没有提高。完成剧本花了 9 个小时。 df1 有 25k 条记录,df2 有 720k 条记录

标签: python pandas


【解决方案1】:

我尝试使用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】:

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

【讨论】:

  • @varsha Shah - 这是否减少了时间?
【解决方案3】:

我想你要找的是pandas.concat

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

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

【讨论】:

  • OP 正在寻找更快更有效的方法,您的回答如何解决这个问题?
猜你喜欢
  • 1970-01-01
  • 2021-11-15
  • 2018-06-28
  • 2016-07-30
  • 1970-01-01
  • 1970-01-01
  • 2021-01-16
  • 2017-07-01
  • 1970-01-01
相关资源
最近更新 更多