代码之家  ›  专栏  ›  技术社区  ›  mr.bjerre

有效地查找字符串列表中的所有子字符串

  •  2
  • mr.bjerre  · 技术社区  · 7 年前

    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
    

    对于每个 制造商 我希望找到的价值 描述 身份证件 通过

    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      []
    

    问题是我需要一个高性能的算法。提供的那一个不能很好地扩展。问题是,是否有任何好的可伸缩算法来解决这个问题?作为参考,最后一次通话需要42秒左右的时间在一个像样的桌面上 n = 10000 .

    1 回复  |  直到 7 年前
        1
  •  1
  •   jezrael    7 年前

    使用嵌套 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)