好的,这是我现有的代码:
////////////// = []
for line in datafile:
splitline = line.split()
for item in splitline:
if not item.endswith("JAX"):
if item.startswith("STF") or item.startswith("BRACKER"):
//////////.append( item )
for line in //////////
print /////////////
/////////// +=1
for t in//////
if t in line[:line.find(',')]:
line = line.strip().split(',')
///////////////write(','.join(line[:3]) + '\n')
break
/////////////.close()
/////////////close()
///////////.close()
我想进一步优化。该文件非常大。我想删除它们匹配后匹配并写入小文件的行,以减少搜索大文件所需的时间。关于我应该怎么做的任何建议?
答案 0 :(得分:1)
你无法删除文本文件中的行 - 它需要在删除的行之后移动所有数据以填补空白,并且效率非常低。
执行此操作的一种方法是使用要保留在bigfile.txt中的所有行编写临时文件,并在完成处理后删除bigfile.txt并重命名临时文件以替换它。
或者,如果bigfile.txt足够小以适应内存,则可以将整个文件读入列表并从列表中删除行,然后将列表写回磁盘。
我还会从你的代码中猜到bigfile.txt是某种CSV文件。如果是这样,那么最好将其转换为数据库文件并使用SQL进行查询。 Python内置了SQLite模块,大多数其他数据库都有第三方库。
答案 1 :(得分:0)
正如我在评论中所说,它并不像我看起来像“bigfile”的大小应该会减慢计数增加的速度。当你迭代这样的文件时,Python只是按顺序一次读取一行。
此时您可以执行的优化取决于matchesLines的大小,以及matchedLines字符串与您正在查看的文本之间的关系。
如果matchedLines很大,只需执行一次'find'就可以节省时间:
for line in completedataset:
text = line[:line.find(',')]
for t in matchedLines:
if t in text:
line = line.strip().split(',')
smallerdataset.write(','.join(line[:3]) + '\n')
break
在我的测试中,'find'花了大约300纳秒,所以如果matchLines是几百万个项目,那么你的额外第二个就在那里。
如果您正在寻找完全匹配,而不是子字符串匹配,您可以使用集合加快速度:
matchedLines = set(matchedLines)
for line in completedataset:
target = line[:line.find(',')]
## One lookup and you're done!
if target in matchedLines:
line = line.strip().split(',')
smallerdataset.write(','.join(line[:3]) + '\n')
如果不匹配的目标文本看起来与看起来完全不同(例如,大多数目标是随机字符串,而匹配的列是一串名称)并且匹配的列都高于一定长度,你可以尝试通过检查子串来变得非常聪明。假设所有匹配的线都至少有5个字符......
def subkeys(s):
## e.g. if len(s) is 7, return s[0:5], s[1:6], s[2:7].
return [s[i:i+5] for i in range(len(s) + 1 - 5)]
existing_subkeys = set()
for line in matchedLines:
existing_subkeys.update(subkeys(line))
for line in completedataset:
target = line[:line.find(',')]
might_match = False
for subkey in subkeys(target):
if subkey in existing_subkeys:
might_match = True
break
if might_match:
# Then we have to do the old slow way.
for matchedLine in matchedLines:
if matchedLine in target:
# Do the split and write and so on.
但尝试做这样的事情真的很容易让自己聪明,这取决于你的数据是什么样的。