python - 如何加快对数百万行的多个 str.contains 搜索?

标签 python regex pandas

我有一个我试图标准化的商店名称数据框。在这里测试的小样本:

import pandas as pd

df = pd.DataFrame({'store': pd.Series(['McDonalds', 'Lidls', 'Lidl New York 123', 'KFC', 'Lidi Berlin', 'Wallmart LA 90210', 'Aldi', 'London Lidl', 'Aldi627', 'mcdonaldsabc123', 'Mcdonald_s', 'McDonalds12345', 'McDonalds5555', 'McDonalds888', 'Aldi123', 'KFC-786', 'KFC-908', 'McDonalds511', 'GerALDInes Shop'],dtype='object',index=pd.RangeIndex(start=0, stop=19, step=1)), 'standard': pd.Series([pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan, pd.np.nan],dtype='float64',index=pd.RangeIndex(start=0, stop=19, step=1))}, index=pd.RangeIndex(start=0, stop=19, step=1))

                store  standard
0           McDonalds       NaN
1               Lidls       NaN
2   Lidl New York 123       NaN
3                 KFC       NaN
4         Lidi Berlin       NaN
5   Wallmart LA 90210       NaN
6                Aldi       NaN
7         London Lidl       NaN
8             Aldi627       NaN
9     mcdonaldsabc123       NaN
10         Mcdonald_s       NaN
11     McDonalds12345       NaN
12      McDonalds5555       NaN
13       McDonalds888       NaN
14            Aldi123       NaN
15            KFC-786       NaN
16            KFC-908       NaN
17       McDonalds511       NaN
18    GerALDInes Shop       NaN

我设置了一个正则表达式字典来搜索一个字符串,并将商店名称的标准化版本插入到列standard中。 .这适用于这个小数据框:
# set up the dictionary
regex_dict = {
 "McDonalds": r'(mcdonalds|mcdonald_s)',
 "Lidl" : r'(lidl|lidi)',
 "Wallmart":r'wallmart',
 "KFC": r'KFC',
 "Aldi":r'(\baldi\b|\baldi\d+)'
}

# loop through dictionary, using str.replace 
for regname, regex_formula in regex_dict.items(): 

    df.loc[df['store'].str.contains(regex_formula,na=False,flags=re.I), 'standard'] = regname

print(df)

                store   standard
0           McDonalds  McDonalds
1               Lidls       Lidl
2   Lidl New York 123       Lidl
3                 KFC        KFC
4         Lidi Berlin       Lidl
5   Wallmart LA 90210   Wallmart
6                Aldi       Aldi
7         London Lidl       Lidl
8             Aldi627       Aldi
9     mcdonaldsabc123  McDonalds
10         Mcdonald_s  McDonalds
11     McDonalds12345  McDonalds
12      McDonalds5555  McDonalds
13       McDonalds888  McDonalds
14            Aldi123       Aldi
15            KFC-786        KFC
16            KFC-908        KFC
17       McDonalds511  McDonalds
18    GerALDInes Shop        NaN

问题是我有大约六百万行要标准化,正则表达式字典比这里显示的要大得多。 (许多不同的商店名称,有一些拼写错误等)

我想做的是在每个循环中,只使用 str.contains对于具有 的行不是 已标准化,并忽略已标准化的行。这个想法是减少每个循环的搜索空间,从而减少整体处理时间。

我已经通过 standard 测试了索引专栏,只表演str.containsstandard 的行上是 Nan ,但它不会导致任何真正的加速。找出哪些行是 Nan 仍然需要时间申请前str.contains .

这是我试图减少每个循环的处理时间的方法:
for regname, regex_formula in regex_dict.items(): 

    # only apply str.contains to rows where standard == NAN
    df.loc[df['standard'].isnull() & df['store'].str.contains(regex_formula,na=False,flags=re.I), 'standard'] = regname

这有效..但是在我的全部 600 万行上使用它对速度没有真正的影响。

甚至有可能在 600 万行的数据帧上加快速度吗?

最佳答案

另一种方法是先提取组,然后像下面这样替换,你的循环方法仍然更好。

我们需要稍微改变 regex_dict,

regex_dict = {
 r'mcdonalds|mcdonald_s':"McDonalds",
 r'lidl|lidi':"Lidl",
 r'wallmart': "Wallmart",
 r'kfc':"KFC" ,
 r'aldi|aldi':"Aldi"
}

df.str.extract(r'('+ '|'.join(regex_dict.keys())+')',expand=False).replace(regex_dict,regex=True)
0    McDonalds
1         Lidl
2         Lidl
3          KFC
4         Lidl

关于python - 如何加快对数百万行的多个 str.contains 搜索?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60015726/

相关文章:

Python 列表范围访问作为环形缓冲区

regex - 无法识别的转义\m 在 PERL 的正则表达式错误中通过

c++ - Boost RegEx 中的等号

python - Pandas 数据框 : Finding entries that share values (e. g。所有包含玩家的游戏)

python - 如何使用python日期时间函数/增量?

python - python lambda 表达式中的 "self"

python - 在 docker 容器中使用 uwsgi 和 nginx 设置 Flask 应用程序

Javascript 正则表达式匹配字符串中的一种模式但排除另一种模式

python - 在pandas中groupby之后重新排列列

python - 填充源 - 目标对和列表中的标志