2013-10-17 106 views
0

我需要遍历数百万次的两个文件, 统计整个文件中单词对出现的次数。 (为了打造的两个词列联表来计算费希尔精确检验得分)Python:通过文件快速迭代

我目前使用

from itertools import izip 
src=tuple(open('src.txt','r')) 
tgt=tuple(open('tgt.txt','r')) 
w1count=0 
w2count=0 
w1='someword' 
w2='anotherword' 
for x,y in izip(src,tgt): 
    if w1 in x: 
     w1count+=1 
    if w2 in y: 
     w2count+=1 
    ..... 

虽然这是不坏,我想知道是否有任何更快的方法遍历两个文件,希望显着更快。

我很感谢你的帮助。

+1

您需要提供更多信息。请澄清您的具体问题或添加更多的细节,以确切地突出你所需要的。正如目前所写,很难确切地说出你在问什么。 –

+0

@InbarRose我添加了更多信息。请让我知道如果它仍然不够:) – ytrewq

+0

那么,仍然有很多信息丢失。你在这里显示的任何代码中使用的任何变量,你应该显示声明,例如:什么是src,tgt,w1,w2,w1count和w2count? –

回答

1

我还是不太明白你想要做什么,但是这里有一些示例代码可能会指出你正确的方向。

我们可以使用一个字典或一个collections.Counter实例来统计所有发生的单词和对在一次通过通过文件。之后,我们只需要查询内存中的数据。

import collections 
import itertools 
import re 

def find_words(line): 
    for match in re.finditer("\w+", line): 
     yield match.group().lower() 

counts1 = collections.Counter() 
counts2 = collections.Counter() 
counts_pairs = collections.Counter() 

with open("src.txt") as f1, open("tgt.txt") as f2: 
    for line1, line2 in itertools.izip(f1, f2): 
     words1 = list(find_words(line1)) 
     words2 = list(find_words(line2)) 
     counts1.update(words1) 
     counts2.update(words2) 
     counts_pairs.update(itertools.product(words1, words2)) 

print counts1["someword"] 
print counts1["anotherword"] 
print counts_pairs["someword", "anotherword"] 
+0

谢谢soooo多!!!!!! – ytrewq

+0

对不起,还有一个问题。运行此程序后,如何检索每个单词或单词对的数量? – ytrewq

+0

btw我不得不改变你的代码yield str(word).lower() – ytrewq

0

一般来说,如果你的数据是足够小,以适应到内存中,然后你最好的选择是:

  1. 处理前数据到内存

  2. 从内存结构迭代

如果文件很大,您可以预先处理数据结构(如压缩数据),并保存为加载速度快得多的格式,例如pickle在单独的文件中工作,然后处理该文件。

+0

我的文件是37MB和36MB。它足够小以适应内存吗? – ytrewq

+0

@CosmicRabbitMediaInc:几乎可以肯定。但我认为改变你的算法将是正确的方法。 –

+0

@SvenMarnach thanx。有关如何更改算法的任何建议? – ytrewq

0

就像开箱即用的思考解决方案: 您是否尝试将文件制作成Pandas数据框?即我假设你已经从输入中删除了一个单词列表(通过删除诸如。和的阅读符号)并使用input.split('')或类似的东西。然后你可以将它制作成DataFrames,执行一个单词计数然后进行笛卡尔连接?

import pandas as pd 
df_1 = pd.DataFrame(src, columns=['word_1']) 
df_1['count_1'] = 1 
df_1 = df_1.groupby(['word_1']).sum() 
df_1 = df_1.reset_index() 

df_2 = pd.DataFrame(trg, columns=['word_2']) 
df_2['count_2'] = 1 
df_2 = df_2.groupby(['word_2']).sum() 
df_2 = df_2.reset_index() 

df_1['link'] = 1 
df_2['link'] = 1 

result_df = pd.merge(left=df_1, right=df_2, left_on='link', right_on='link') 
del result_df['link'] 

我用这样的东西进行购物篮分析,效果很好。