Python 通过字符串和子字符串连接匹配的数据帧

Python 通过字符串和子字符串连接匹配的数据帧,python,pandas,dataframe,text,Python,Pandas,Dataframe,Text,我想通过部分字符串匹配合并两个数据帧。 我有两个数据帧要合并。第一个df1由130000行组成,如下所示: id text xc1 xc2 1 adidas men shoes 52465 220 2 vakko men suits 49220 224 3 burberry men shirt 78248 289 4

我想通过部分字符串匹配合并两个数据帧。 我有两个数据帧要合并。第一个df1由130000行组成,如下所示:

id    text                        xc1       xc2
1     adidas men shoes            52465     220
2     vakko men suits             49220     224
3     burberry men shirt          78248     289
4     prada women shoes           45780     789
5     lcwaikiki men sunglasses    34788     745
id    keyword               abc1     abc2
1     men shoes             1000     11
2     men suits             2000     12
3     men shirt             3000     13
4     women socks           4000     14
5     men sunglasses        5000     15
id    text                        xc1       xc2   keyword         abc1  abc2
1     adidas men shoes            52465     220   men shoes       1000  11
2     vakko men suits             49220     224   men suits       2000  12
3     burberry men shirt          78248     289   men shirt       3000  13
4     lcwaikiki men sunglasses    34788     745   men sunglasses  5000  15
第二个df2由8000行组成,如下所示:

id    text                        xc1       xc2
1     adidas men shoes            52465     220
2     vakko men suits             49220     224
3     burberry men shirt          78248     289
4     prada women shoes           45780     789
5     lcwaikiki men sunglasses    34788     745
id    keyword               abc1     abc2
1     men shoes             1000     11
2     men suits             2000     12
3     men shirt             3000     13
4     women socks           4000     14
5     men sunglasses        5000     15
id    text                        xc1       xc2   keyword         abc1  abc2
1     adidas men shoes            52465     220   men shoes       1000  11
2     vakko men suits             49220     224   men suits       2000  12
3     burberry men shirt          78248     289   men shirt       3000  13
4     lcwaikiki men sunglasses    34788     745   men sunglasses  5000  15
在匹配关键字文本后,输出应如下所示:

id    text                        xc1       xc2
1     adidas men shoes            52465     220
2     vakko men suits             49220     224
3     burberry men shirt          78248     289
4     prada women shoes           45780     789
5     lcwaikiki men sunglasses    34788     745
id    keyword               abc1     abc2
1     men shoes             1000     11
2     men suits             2000     12
3     men shirt             3000     13
4     women socks           4000     14
5     men sunglasses        5000     15
id    text                        xc1       xc2   keyword         abc1  abc2
1     adidas men shoes            52465     220   men shoes       1000  11
2     vakko men suits             49220     224   men suits       2000  12
3     burberry men shirt          78248     289   men shirt       3000  13
4     lcwaikiki men sunglasses    34788     745   men sunglasses  5000  15

让我们首先对关键词进行排序,以便“女士套装”与“男士套装”之前的“匹配”

现在定义一个匹配函数;
df1
中的每个
text
值将作为
s
传递,以查找匹配的关键字:

def is_match(arr, s):
    for a in arr:
        if a in s:
            return a
    return None
现在,我们可以从df1中的每个
文本中提取关键字,并将其添加到新列中:

df1['keyword'] = df1['text'].apply(lambda x: is_match(lkeys, x))
我们现在拥有标准合并所需的一切:

pd.merge(df1, df2, on='keyword')

让我们首先对关键词进行排序,以便“女士套装”与“男士套装”之前的“匹配”

现在定义一个匹配函数;
df1
中的每个
text
值将作为
s
传递,以查找匹配的关键字:

def is_match(arr, s):
    for a in arr:
        if a in s:
            return a
    return None
现在,我们可以从df1中的每个
文本中提取关键字,并将其添加到新列中:

df1['keyword'] = df1['text'].apply(lambda x: is_match(lkeys, x))
我们现在拥有标准合并所需的一切:

pd.merge(df1, df2, on='keyword')

让我们通过交叉连接2个数据帧,然后通过将字符串与子字符串匹配来进行过滤,如下所示:

df3 = df1.merge(df2, how='cross')    # for Pandas version >= 1.2.0 (released in Dec 2020)

import re
mask = df3.apply(lambda x: (re.search(rf"\b{x['keyword']}\b", str(x['text']))) != None, axis=1)
df_out = df3.loc[mask]
如果您的Pandas版本早于1.2.0(于2020年12月发布),并且不支持与
how='cross'
合并,则可以将合并语句替换为:

# For Pandas version < 1.2.0
df3 = df1.assign(key=1).merge(df2.assign(key=1), on='key').drop('key', axis=1)   
这里,
id\u x
列和
id\u y
列分别是
df1
df2
中的原始
id
列。从注释中可以看出,这些只是数据帧的行号,您可能并不关心。然后,我们可以删除这两列并重置索引以清理布局:

df_out = df_out.drop(['id_x', 'id_y'], axis=1).reset_index(drop=True)
最终结果

print(df_out)


                       text    xc1  xc2         keyword  abc1  abc2
0          adidas men shoes  52465  220       men shoes  1000    11
1           vakko men suits  49220  224       men suits  2000    12
2        burberry men shirt  78248  289       men shirt  3000    13
3  lcwaikiki men sunglasses  34788  745  men sunglasses  5000    15

让我们通过交叉连接2个数据帧,然后通过将字符串与子字符串匹配来进行过滤,如下所示:

df3 = df1.merge(df2, how='cross')    # for Pandas version >= 1.2.0 (released in Dec 2020)

import re
mask = df3.apply(lambda x: (re.search(rf"\b{x['keyword']}\b", str(x['text']))) != None, axis=1)
df_out = df3.loc[mask]
如果您的Pandas版本早于1.2.0(于2020年12月发布),并且不支持与
how='cross'
合并,则可以将合并语句替换为:

# For Pandas version < 1.2.0
df3 = df1.assign(key=1).merge(df2.assign(key=1), on='key').drop('key', axis=1)   
这里,
id\u x
列和
id\u y
列分别是
df1
df2
中的原始
id
列。从注释中可以看出,这些只是数据帧的行号,您可能并不关心。然后,我们可以删除这两列并重置索引以清理布局:

df_out = df_out.drop(['id_x', 'id_y'], axis=1).reset_index(drop=True)
最终结果

print(df_out)


                       text    xc1  xc2         keyword  abc1  abc2
0          adidas men shoes  52465  220       men shoes  1000    11
1           vakko men suits  49220  224       men suits  2000    12
2        burberry men shirt  78248  289       men shirt  3000    13
3  lcwaikiki men sunglasses  34788  745  men sunglasses  5000    15


部分字符串匹配是否可能位于
df1
中文本的中间?e、 g.
vakko男式西装蓝色
?@SeaBean是的。当我检查数据集时,有这样的例子。id的顺序是否相同?@AnuragDabas不幸的是否。两个数据帧的行号不同。部分字符串匹配可能位于
df1
中文本的中间?e、 g.
vakko男式西装蓝色
?@SeaBean是的。当我检查数据集时,有这样的例子。id的顺序是否相同?@AnuragDabas不幸的是,没有。两个数据帧的行号不同。谢谢你的回答。我猜有些价值观​​包含int值。例如:“16英寸自行车轮辋”。因此,我得到了一个类似这样的错误:
TypeError:int类型的参数不可测试
谢谢你的回答。我猜有些价值观​​包含int值。例如:“16英寸自行车轮辋”。因此,我得到了一个类似这样的错误:
TypeError:int类型的参数不可测试
谢谢你的回答。我得到了一个类似这样的错误:
TypeError:expected string或bytes-like-object
可能包含一些值​​是因为它是整数吗?@muratmert41在这种情况下,使用
str(x['text'])
首先将
x['text']
转换为字符串。您可以参考我上面编辑的代码。@muratmert41如果还有什么需要帮助的,请随时告诉我!:-)你的回答对我帮助很大。我不会再犯错误了。但是有一些小问题妨碍我得到正确的结果。我正在研究它们。@muratmert41如果这与你的问题有关,看看我能不能帮你。如果没有,希望你尽快解决!无论如何,请记住!祝你好运谢谢你的回答。我得到了一个类似这样的错误:
TypeError:expected string或bytes-like-object
可能包含一些值​​是因为它是整数吗?@muratmert41在这种情况下,使用
str(x['text'])
首先将
x['text']
转换为字符串。您可以参考我上面编辑的代码。@muratmert41如果还有什么需要帮助的,请随时告诉我!:-)你的回答对我帮助很大。我不会再犯错误了。但是有一些小问题妨碍我得到正确的结果。我正在研究它们。@muratmert41如果这与你的问题有关,看看我能不能帮你。如果没有,希望你尽快解决!无论如何,请记住!祝你好运