【问题标题】:Effeciently finding all substrings in list of strings有效地查找字符串列表中的所有子字符串
【发布时间】:2019-02-17 22:20:37
【问题描述】:

想象一个大的pandas 数据框由

import string
import random
import pandas as pd

n = 10000

def id_generator(chars=string.ascii_uppercase + string.digits, size=6):
    return ''.join(random.choice(chars) for _ in range(size))


mfr = [id_generator(size=random.randint(3, 20)) for _ in range(n)]
desc = [id_generator(size=random.randint(3, 50)) +
        (' ' + random.choice(mfr) if random.random() > 0.8 else '') for _ in range(n)]

df = pd.DataFrame({'id': range(n), 'mfr': mfr, 'desc': desc}).set_index('id')

产生

                   mfr                                               desc
id                                                                       
0              XACYXAB                            6JYLELA2WUR1MVOS5 1VKF5
1   JOLB082YROZO97PGS5  YWWTUR4A19JKVB5HLBQ9RKVHNJ10J08SQZZHSLG2IB 4MK...
2                 88QO                            DUV566OX9OLSLZJZR9CRWNT
3        DW4S6WTRGWJVE                                                MFE
4             Z2I5VOWK                 IX5DY8GLSPGD5R8W350DZ6ED8CGN2C20GA

对于每个 mfr 值,我希望找到包含该值作为子字符串的 desc,并返回相应的 id。这可以在pandas 中通过

完成
df['matches'] = df.mfr.map(lambda x: df.index[df.desc.str.contains(x)].tolist())

给出想要的结果

                   mfr                                               desc matches
id                                                                               
0              XACYXAB                            6JYLELA2WUR1MVOS5 1VKF5      []
1   JOLB082YROZO97PGS5  YWWTUR4A19JKVB5HLBQ9RKVHNJ10J08SQZZHSLG2IB 4MK...      []
2                 88QO                            DUV566OX9OLSLZJZR9CRWNT      []
3        DW4S6WTRGWJVE                                                MFE      []
4             Z2I5VOWK                 IX5DY8GLSPGD5R8W350DZ6ED8CGN2C20GA      []
5   UPCTNHIF2BOAGOB2WL                  MB2GCMRLQTYD1YRGBJILQ0CZ3LCR2FYHX      []
6              L8K9E3T                                         WW0M73FPD4      []
7                  ZQT               NWNMFRB1ZTMKUVXZH0BFTSIOC3R84XSPRLJS   [532]
8       SPEJJW1JGGSG8B                           7NYL32KTN8ZRNYDV2Z NK4T3      []
9               3WWZ46                Z3HVNIBSQVXJG5487YX7EA89SYPHN5M3BJ2      []

问题是我需要一个高性能的算法。提供的那个不能很好地扩展。问题是对于这个问题是否存在任何好的可扩展算法?作为参考,在使用 n = 10000 的体面桌面上,最后一次调用需要大约 42 秒。

【问题讨论】:

    标签: python string pandas search


    【解决方案1】:

    使用嵌套的list comprehension:

    n = 1000
    
    d = df['desc'].to_dict()
    
    In [117]: %timeit df['matches1'] = [[k for k, v in d.items() if x in v] for x in df.mfr]
    80.8 ms ± 2.81 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    
    In [118]: %timeit df['matches'] = df.mfr.map(lambda x: df.index[df.desc.str.contains(x)].tolist())
    877 ms ± 27.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-18
      • 2013-07-01
      • 2017-08-05
      • 1970-01-01
      • 1970-01-01
      • 2012-10-24
      • 1970-01-01
      相关资源
      最近更新 更多