2012-06-15 44 views
0

我有10GB数据的格式如下:如何高效地搜索文件中的字符串?

A=good 
B=c++ 

现在我想找出B的。例如,我希望找出“C++”,因为对于这种情况...我为这个问题所遵循的方法是选择B部分(即第一行),然后从中找出一个字符串,它等于到B的字符串。然后在第二轮循环中。我在寻找另一个B值(现在是第4行),并从那里找到一个B,它具有相等的字符串....等等

但是,上述方法需要很多时间,Python中是否有其他方法可以有效地解决这个问题。

+0

只是使用数据库和搜索。 – JBernardo

回答

8

由于您的文件过大,很容易装入内存,怎么样:

  1. 分为两个文件,A和B各
  2. 排序(例如,使用UNIX sort或Python的外部存储器归并)
  3. 做归并的合并步骤,找到重复
+0

我没有得到..如何排序文件后,它会帮助我...你能解释一下 – user1355603

+1

请参阅http://en.wikipedia.org/wiki/Mergesort的合并功能。基本思想是逐步浏览两个文件(A和B)并进行比较。例如,从文件A中选择第一行,然后遍历B,直到找到一个大于A中的行的值。此时,您知道可以跳过B文件的其余部分,并从文件A中获取嵌套行并继续这个过程。最重要的是,没有内存限制 - 这可以在10TB文件上运行(虽然速度很慢)。 –

+0

+1,考虑到对内存的限制,这将是要走的路。 –

2

这样做的最好方法是读取数据,构建一组A项目和一组B项目。然后你只需找到两者的交集。

唯一潜在的缺点是您需要一次将所有数据放入内存中。鉴于你的大数据集,这可能是一个问题。如果你可以处理一半,那么你可以创建你的一套A项目,然后通过B项目检查该集合。

实施例:

使用输入数据:

A=good 
B=c++ 
A=df 
B=kj 
A=c++ 
B=programming language 

第一种方法,可以简单地完成像这样:

a = set() 
b = set() 
with open("test") as data: 
    for line in data: 
     line_data = line[2:].strip() 
     if line.startswith("A"): 
      a.add(line_data) 
     else: 
      b.add(line_data) 

print(a & b) 

给予我们:

{'c++'} 

的第二种方法可以b大功告成像这样:

with open("test") as data: 
    a = {line[2:].strip() for line in data if line.startswith("A")} 

with open("test") as data: 
    results = {item for item in (line[2:].strip() for line in data if line.startswith("B")) if item in a} 

print(results) 

这给了相同的结果,而只有涉及到存储数据的一半内存(或更少,如果有数据的显著重复),并且仍然是更为有效的由于有效设置查找的性质。

+0

ya ..但是我的文件我们的10GB – user1355603

+0

@ user1355603因此,内存中的全部或部分数据都不可行吗? –

+0

是的...因为我的问题是我正在寻找的B可能是在文件的末尾或中间...我不确定这个 – user1355603

0

运行以下命令:

cat huge_file | awk 'BEGIN {FS = "="} { print $2 "***" $1 }' | sort -n | awk 'BEGIN {FS = "\\*\\*\\*"} { if (prev == $1 && $2 == "B") { print $1 } prev = $1 }' 

这将它们分成A/B和值,按值排序并找到相邻的对。它假定没有任何字符串具有子字符串“*”,但是您可以用任何其他已知不会显示的子字符串替换该字符串。

1

由于这个数据太大,我建议将它存储在像mysql这样的数据库中。然后用一行查询解决您的问题。

select * from t1,t2 where t1.a=t2.b; 

这是一个替代建议。如果你选择去,mysqldb模块可以帮助你连接python和mysql。