Python 如何高效的在大量文本里面搜索匹配大量词 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
v2zero
V2EX    Python

Python 如何高效的在大量文本里面搜索匹配大量词

  •  1
     
  •   v2zero 2020-04-04 18:27:04 +08:00 4778 次点击
    这是一个创建于 2018 天前的主题,其中的信息可能已经有所发展或是发生改变。

    数千万篇文章,寻找其中包含成语的句子。成语有数万条。

    目前没有对文章内容建立过全文索引,鉴于这个事情是一次性的,为此搞个索引可能也成本过高。

    暂时的解决方案是,把成语都放在一条 re.compile('乌合之众|鸡犬相闻|...')里面去搜索文章,但效率总觉得不理想。

    求教,是否可能有更高效的解决方案。

    14 条回复    2020-04-11 21:11:10 +08:00
    superrichman
        1
    superrichman  
       2020-04-04 18:36:41 +08:00 via iPhone
    文章内容很长的话,正则的效率是很低的。全文搜索还是要用 elasticsearch 或者 solr 比较靠谱。
    fishCatcher
        2
    fishCatcher  
       2020-04-04 18:38:40 +08:00 via iPhone   3
    AC 自动机
    ClericPy
        3
    ClericPy  
       2020-04-04 19:06:58 +08:00   1
    直接套 AC 自动机, 专门搞敏感词过滤和发现的, 现成的库就挺快了, 貌似是 C 写的给 py 调

    套正则, 四五万字的 "或" 条件, 还不如直接用 Python 字符串的 for 和 in
    ypw
        4
    ypw  
       2020-04-04 19:08:11 +08:00
    成语长度固定四个字的话,建一个集合 set,然后暴力搜也是可以的,复杂度 O(n),与成语集合大小无关。
    v2zero
        5
    v2zero  
    OP
       2020-04-04 19:10:24 +08:00
    @fishCatcher 感动,一个词解决一个大难题。业余写代码,自己也实现不了这种东西,网上找了个 Python 实现。原来预计一周多的运行时间,瞬间就缩减到一天了。
    v2zero
        6
    v2zero  
    OP
       2020-04-04 19:11:35 +08:00
    @ypw 成语这种东西吧,有的还带逗号。。。也挺麻烦的
    v2zero
        7
    v2zero  
    OP
       2020-04-04 19:12:58 +08:00
    @ClericPy 以前自己做了个敏感词过滤,就是用的正则,现在看来还是蛮蠢的了。
    superrichman
        8
    superrichman  
       2020-04-04 19:16:39 +08:00 via iPhone
    @fishCatcher
    @ClericPy
    涨知识了,感谢
    ClericPy
        9
    ClericPy  
       2020-04-04 20:02:13 +08:00
    @v2zero #7 这事我实习时候干过啊... 不过不是用竖线, 用的是超长裹脚布版的零宽断言...... 后来发现还不如一个个 in 去判断呢...

    @superrichman #8 你这么提问其实挺好的, 背景, 思路, 自己的尝试, 甚至没什么语文错误
    上次见一个类似的需求, 说了一大堆自己的思路, 实际一开始就跑偏了, 带着起码二十多楼跟着歪了, 哈哈, 共同学习
    lithbitren
        10
    lithbitren  
       2020-04-04 20:29:40 +08:00 via iPhone
    @ClericPy 带佬,有稳定好用 py3 支持 utf8 的 ac 自动机 c 拓展嘛,我之前没找到,自己用纯 py 手撕了一个,算法上应该优化到极限了,但 40 万词启动还建树是用了两秒多,查词还好基本忽略不计了,用起来没啥问题,就是启动太难。
    ClericPy
        11
    ClericPy  
       2020-04-04 20:56:13 +08:00
    @lithbitren #10 你手撸已经比我强多了... 我都五六年没动 NLP 的东西了...
    lithbitren
        12
    lithbitren  
       2020-04-05 22:32:48 +08:00
    说起来,当时找 ac 自动机解决方案还是有坑的,py 的对于复杂算法的模板不多,csdn 上搜到的 py 的 ac 自动机是有问题,建树竟然用 remove 首元素来处理队列,让队列处理在 c 层面的时间复杂度变成了 O(N^2),小规模的屏蔽词过滤看不出啥,大规模词语处理时间会陡增,40 万词要处理将近四分钟,不过改数据解构用 deque 和 popleft 大概就好了。另外搜到过 2 个 pipy 上的开源库,一个是 py2 时代的,一个是重叠的关键字词输出会有问题,最后才决定手撸的。。
    qsnow6
        13
    qsnow6  
       2020-04-11 17:33:22 +08:00
    @v2zero #7
    之前在过滤 black list 时找过相关的资料,长文本的搜索适合上 AC 自动机。短文本建议直接 x in s 就完事了,Python 编译器做了优化,效率更快,写起来也方便。

    可以看这个答案: https://stackoverflow.com/questions/3389574/check-if-multiple-strings-exist-in-another-string#comment105454320_3389574

    PS:楼主是做 SEO 的?可以加个好友交流下啊,我平时接触爬虫、数据清洗、NLP 这些领域比较多。
    v2zero
        14
    v2zero  
    OP
       2020-04-11 21:11:10 +08:00
    @qsnow6 过于明显了么。微信,去空格: 182 1055 2814
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1465 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 16:44 PVG 00:44 LAX 09:44 JFK 12:44
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86