我有10GB数据的格式如下:如何高效地搜索文件中的字符串?
A=good
B=c++
现在我想找出B的。例如,我希望找出“C++”,因为对于这种情况...我为这个问题所遵循的方法是选择B部分(即第一行),然后从中找出一个字符串,它等于到B的字符串。然后在第二轮循环中。我在寻找另一个B值(现在是第4行),并从那里找到一个B,它具有相等的字符串....等等
但是,上述方法需要很多时间,Python中是否有其他方法可以有效地解决这个问题。
我有10GB数据的格式如下:如何高效地搜索文件中的字符串?
A=good
B=c++
现在我想找出B的。例如,我希望找出“C++”,因为对于这种情况...我为这个问题所遵循的方法是选择B部分(即第一行),然后从中找出一个字符串,它等于到B的字符串。然后在第二轮循环中。我在寻找另一个B值(现在是第4行),并从那里找到一个B,它具有相等的字符串....等等
但是,上述方法需要很多时间,Python中是否有其他方法可以有效地解决这个问题。
由于您的文件过大,很容易装入内存,怎么样:
sort
或Python的外部存储器归并)我没有得到..如何排序文件后,它会帮助我...你能解释一下 – user1355603
请参阅http://en.wikipedia.org/wiki/Mergesort的合并功能。基本思想是逐步浏览两个文件(A和B)并进行比较。例如,从文件A中选择第一行,然后遍历B,直到找到一个大于A中的行的值。此时,您知道可以跳过B文件的其余部分,并从文件A中获取嵌套行并继续这个过程。最重要的是,没有内存限制 - 这可以在10TB文件上运行(虽然速度很慢)。 –
+1,考虑到对内存的限制,这将是要走的路。 –
这样做的最好方法是读取数据,构建一组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)
这给了相同的结果,而只有涉及到存储数据的一半内存(或更少,如果有数据的显著重复),并且仍然是更为有效的由于有效设置查找的性质。
ya ..但是我的文件我们的10GB – user1355603
@ user1355603因此,内存中的全部或部分数据都不可行吗? –
是的...因为我的问题是我正在寻找的B可能是在文件的末尾或中间...我不确定这个 – user1355603
运行以下命令:
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和值,按值排序并找到相邻的对。它假定没有任何字符串具有子字符串“*”,但是您可以用任何其他已知不会显示的子字符串替换该字符串。
由于这个数据太大,我建议将它存储在像mysql这样的数据库中。然后用一行查询解决您的问题。
select * from t1,t2 where t1.a=t2.b;
这是一个替代建议。如果你选择去,mysqldb模块可以帮助你连接python和mysql。
只是使用数据库和搜索。 – JBernardo