使用Python在两个大数据帧中搜索匹配字符串的最快方法

使用Python在两个大数据帧中搜索匹配字符串的最快方法,python,performance,pandas,dataframe,Python,Performance,Pandas,Dataframe,我有两个大数据帧df1-->100K行和df2-->600K行,它们如下所示 # df1 name price brand model 0 CANON CAMERA 20 FS36dINFS MEGAPIXEL 9900.0 CANON FS36dINFS 1 SONY HD CAMERA 25 MEGAPIXEL 8900.0 SONY

我有两个大数据帧
df1-->100K
行和
df2-->600K
行,它们如下所示

# df1
                                      name   price    brand  model 
0       CANON CAMERA 20 FS36dINFS MEGAPIXEL  9900.0   CANON  FS36dINFS     
1               SONY HD CAMERA 25 MEGAPIXEL  8900.0    SONY         
2       LG 55" 4K UHD LED Smart TV 55UJ635V  5890.0     LG   55UJ635V       
3      Sony 65" LED Smart TV KD-65XD8505BAE  4790.0    SONY  KD-65XD8505BAE     
4       LG 49" 4K UHD LED Smart TV 49UJ651V  4390.0      LG  49UJ651V     

#df2

                                  name       store      price
0     LG 49" 4K UHD LED Smart TV 49UJ651V     storeA   4790.0
1             SONY HD CAMERA 25 MEGAPIXEL     storeA   12.90
2  Samsung 32" LED Smart TV UE-32J4505XXE     storeB    1.30
datalist = []
for idx1, row1 in df1.iterrow():
    for idx2, row2 in df2.iterrows():
        if(row1['brand'] in row2['name'] and row1['model'] in row2['name']):
                datalist.append([row1['model'],  row1['brand'], row1['name'],  row1['price'], row2['name'],row2['price'], row2['store']])
我想匹配来自df1的品牌和其他功能是否在df2中,如果它们存在,那么我会做一些事情。目前,我正在使用一种简单的方法来迭代两个数据帧,如下所示

# df1
                                      name   price    brand  model 
0       CANON CAMERA 20 FS36dINFS MEGAPIXEL  9900.0   CANON  FS36dINFS     
1               SONY HD CAMERA 25 MEGAPIXEL  8900.0    SONY         
2       LG 55" 4K UHD LED Smart TV 55UJ635V  5890.0     LG   55UJ635V       
3      Sony 65" LED Smart TV KD-65XD8505BAE  4790.0    SONY  KD-65XD8505BAE     
4       LG 49" 4K UHD LED Smart TV 49UJ651V  4390.0      LG  49UJ651V     

#df2

                                  name       store      price
0     LG 49" 4K UHD LED Smart TV 49UJ651V     storeA   4790.0
1             SONY HD CAMERA 25 MEGAPIXEL     storeA   12.90
2  Samsung 32" LED Smart TV UE-32J4505XXE     storeB    1.30
datalist = []
for idx1, row1 in df1.iterrow():
    for idx2, row2 in df2.iterrows():
        if(row1['brand'] in row2['name'] and row1['model'] in row2['name']):
                datalist.append([row1['model'],  row1['brand'], row1['name'],  row1['price'], row2['name'],row2['price'], row2['store']])

但这需要很多时间,因为两个数据帧都很大。我研究过集合速度更快,但在这里,我使用iterrows使用数据帧的方式无法转换为集合,因为那样我将失去位置。有更快的方法吗?

如果在
df1['brand']
df1['model']
中有大量重复,那么您可以通过为品牌和模型创建正则表达式模式来提高性能:

brands = '({})'.format('|'.join(df1['brand'].dropna().unique()))
# '(CANON|SONY|LG)'
models = '({})'.format('|'.join(df1['model'].dropna().unique()))
# '(FS36dINFS|55UJ635V|KD-65XD8505BAE|49UJ651V)'
然后可以使用
str.extract
方法从
df2['name']
中查找品牌和型号字符串:

df2['brand'] = df2['name'].str.extract(brands, expand=False)
df2['model'] = df2['name'].str.extract(models, expand=False)
然后,您可以通过执行内部合并以数据帧的形式获得所需的数据:

result = pd.merge(df1.dropna(subset=bm), df2.dropna(subset=bm), on=bm, how='inner')

屈服

  brand     model                               name_x  price_x                               name_y  price_y   store
0    LG  49UJ651V  LG 49" 4K UHD LED Smart TV 49UJ651V   4390.0  LG 49" 4K UHD LED Smart TV 49UJ651V   4790.0  storeA

如果在
df1['brand']
df1['model']
中存在大量重复,那么您可以通过为品牌和模型创建正则表达式模式来提高性能:

brands = '({})'.format('|'.join(df1['brand'].dropna().unique()))
# '(CANON|SONY|LG)'
models = '({})'.format('|'.join(df1['model'].dropna().unique()))
# '(FS36dINFS|55UJ635V|KD-65XD8505BAE|49UJ651V)'
然后可以使用
str.extract
方法从
df2['name']
中查找品牌和型号字符串:

df2['brand'] = df2['name'].str.extract(brands, expand=False)
df2['model'] = df2['name'].str.extract(models, expand=False)
然后,您可以通过执行内部合并以数据帧的形式获得所需的数据:

result = pd.merge(df1.dropna(subset=bm), df2.dropna(subset=bm), on=bm, how='inner')

屈服

  brand     model                               name_x  price_x                               name_y  price_y   store
0    LG  49UJ651V  LG 49" 4K UHD LED Smart TV 49UJ651V   4390.0  LG 49" 4K UHD LED Smart TV 49UJ651V   4790.0  storeA

当我运行代码时,它抛出
sre_常量。错误:在第行
df2[col]=df2['name']]的位置515858处多次重复。str.extract(pat,expand=False)
。。。我认为第
515858行的数据中存在一些问题,因此我暂时删除了该行,但它仍然会在相同的位置抛出相同的错误可能有一些字符在
品牌
模型
中,例如对正则表达式引擎具有特殊意义的反斜杠字符,而我们希望将该字符视为字符串文字。解决方案是对我们想要解释为字符串文字的字符串调用
re.escape
。我已经更新了代码来说明我的意思。非常感谢!我花了很多时间来弄清楚这一点当我运行代码时,它抛出了
sre_常量。错误:在第行
df2[col]=df2['name']]的位置515858
多次重复。str.extract(pat,expand=False)
。。。我认为第
515858行的数据中存在一些问题,因此我暂时删除了该行,但它仍然会在相同的位置抛出相同的错误可能有一些字符在
品牌
模型
中,例如对正则表达式引擎具有特殊意义的反斜杠字符,而我们希望将该字符视为字符串文字。解决方案是对我们想要解释为字符串文字的字符串调用
re.escape
。我已经更新了代码来说明我的意思。非常感谢!我花了很多时间来弄明白这一点