0

我有一个包含几个观察结果的文本文件。每个观察都在一行中。我想检测一行中每个单词的唯一出现。换句话说,如果同一个词在同一行出现两次或多次,它仍然算作一次。但是,我想计算所有观察中每个单词的出现频率。这意味着如果一个单词出现在两行或多行中,我想计算它出现的行数。这是我编写的程序,它在处理大量文件时真的很慢。我还通过引用另一个文件来删除文件中的某些单词。请提供有关如何提高速度的建议。谢谢你。

import re, string
from itertools import chain, tee, izip
from collections import defaultdict

def count_words(in_file="",del_file="",out_file=""):

    d_list = re.split('\n', file(del_file).read().lower())
    d_list = [x.strip(' ') for x in d_list] 

    dict2={}
    f1 = open(in_file,'r')
    lines = map(string.strip,map(str.lower,f1.readlines()))

    for line in lines:
        dict1={}
        new_list = []
        for char in line:
            new_list.append(re.sub(r'[0-9#$?*_><@\(\)&;:,.!-+%=\[\]\-\/\^]', "_", char))
        s=''.join(new_list)
        for word in d_list:
            s = s.replace(word,"")
        for word in s.split():
            try:
                dict1[word]=1
            except:
                dict1[word]=1
        for word in dict1.keys():
            try:
                dict2[word] += 1
            except:
                dict2[word] = 1
    freq_list = dict2.items()
    freq_list.sort()
    f1.close()

    word_count_handle = open(out_file,'w+')
    for word, freq  in freq_list:
        print>>word_count_handle,word, freq
    word_count_handle.close()
    return dict2

 dict = count_words("in_file.txt","delete_words.txt","out_file.txt")
4

3 回答 3

1

您在该行的每个字符上运行 re.sub ,一次一个。那很慢。在整行上执行:

s = re.sub(r'[0-9#$?*_><@\(\)&;:,.!-+%=\[\]\-\/\^]', "_", line)

另外,请查看集合模块中的集合和 Counter 类。如果您只是数数然后丢弃您不想要的那些,它可能会更快。

于 2011-09-30T02:21:44.623 回答
1

在没有进行任何性能测试的情况下,想到以下内容:

1)你正在使用正则表达式——为什么?你只是想摆脱某些角色吗?

2)您正在使用异常进行流控制——尽管它可能是 Pythonic(请求宽恕而不是许可),但抛出异常通常会很慢。如此处所示:

    for word in dict1.keys():
        try:
            dict2[word] += 1
        except:
            dict2[word] = 1

3)变成d_list一个集合,并使用pythonin测试成员资格,同时......

4)避免在字符串上大量使用replace方法——我相信你正在使用它来过滤掉出现在d_list. 这可以通过避免 来实现replace,并且只过滤行中的单词,或者使用列表理解:

[word for word words if not word in del_words]

或使用过滤器(不是很pythonic):

filter(lambda word: not word in del_words, words)
于 2011-09-30T02:30:12.780 回答
0
import re

u_words        = set()
u_words_in_lns = []
wordcount      = {}
words          = []

# get unique words per line
for line in buff.split('\n'):
    u_words_in_lns.append(set(line.split(' ')))

# create a set of all unique words
map( u_words.update, u_words_in_lns )

# flatten the sets into a single list of words again
map( words.extend, u_words_in_lns)

# count everything up
for word in u_words:
    wordcount[word] = len(re.findall(word,str(words)))
于 2011-09-30T06:23:29.473 回答