我有两个熊猫数据帧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
答案 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)