在python中对大文件优化正则表达式和文件读取操作

时间:2015-02-06 14:26:05

标签: python regex optimization profile

现在我有两个大文件,模式文件日志文件,每个文件都有超过300,000行。模式文件具有以下格式:

Line 1 : <ID>   <Dialog1>    <ReplyStr>    <Dialog2>    
// the ReplyStr is needed as a pattern

日志文件的格式为:

Line 1 : <LogData>    <ReplyStr>    <CommentOfReply>   
// get all CommentOfReply, whose ReplyStr is from the pattern file

我的任务是从特定回复中获取所有评论,以便分析用户对这些回复的情感。所以这就是我一步一步做的事情:

  1. 使用正则表达式选择所有模式和日志,
  2. 然后将它们与字符串比较操作匹配在一起。
  3. 我需要优化代码,现在需要8个小时才能完成。

    配置文件如下(在前10个循环中使用cProfile):

       ncalls  tottime  percall  cumtime  percall filename:lineno(function)
            1    0.000    0.000   19.345   19.345 <string>:1(<module>)
            1    7.275    7.275   19.345   19.345 get_candidate2.py:12(foo)
      3331494    2.239    0.000   10.772    0.000 re.py:139(search)
      3331496    4.314    0.000    5.293    0.000 re.py:226(_compile)
          7/2    0.000    0.000    0.000    0.000 sre_compile.py:32(_compile)
                                ......
      3331507    0.632    0.000    0.632    0.000 {method 'get' of 'dict' objects}
      3331260    0.560    0.000    0.560    0.000 {method 'group' of '_sre.SRE_Match' objects}
            2    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}
            2    0.000    0.000    0.000    0.000 {method 'remove' of 'list' objects}
      3331494    3.241    0.000    3.241    0.000 {method 'search' of '_sre.SRE_Pattern' objects}
            9    0.000    0.000    0.000    0.000 {method 'split' of 'str' objects}
      6662529    0.737    0.000    0.737    0.000 {method 'strip' of 'str' objects}
    

    从个人资料中,似乎所有耗时都来自re.search()。我不知道如何减少它。

1 个答案:

答案 0 :(得分:2)

感谢@MikeSatteson和@tobias_k的帮助,我明白了。

要挑选出与给定回复字符串相对应的所有评论字符串(来自日志文件)(来自模式文件),解决方案是:

  1. 需要一个dict,其键是回复字符串,value是注释字符串列表。
  2. 模式文件中挑选所有回复字符串,作为字典的密钥集。
  3. 日志文件中挑选所有回复 - 评论对,如果dict的密钥集包含回复,请将评论附加到评论列表。
  4. 以下是代码:

    my_dict = {}
    with open('pattern file', 'r') as pattern_file:
        for line in pattern_file:
            reply = get_reply(line)
            my_dict[reply] = list()     
    
    with open('log file', 'r') as log_file:
        for line in log_file:
            pair = get_comment_reply_pair(line)
            reply = pair.reply
            comment  = pair.comment
            if reply in my_dict:
                l = my_dict[reply]
                l.append(comment)