如何在Python中快速搜索.csv文件
我正在用Python读取一个有600万条记录的.csv文件,我想在这个文件里查找特定的条目。
有没有什么技巧可以搜索整个文件?是把整个文件读到一个字典里,还是每次都进行搜索?我试过把它加载到字典里,但花了很长时间,所以我现在每次都在整个文件里搜索,这样感觉很浪费。
我能否利用这个列表是按字母顺序排列的特点?比如说,如果搜索的词以“b”开头,我只从包含第一个以“b”开头的词的那一行开始搜索,到包含最后一个以“b”开头的词的那一行结束。
我正在使用 import csv
。
(顺便问一下:能否让 csv
跳到文件中的特定行?我想让程序从随机的一行开始。)
编辑:我已经有这个列表的.sql文件的副本,我该如何在Python中使用它?
6 个回答
1
好吧,如果你的单词不太大(也就是说它们能放进内存里),那么这里有一个简单的方法来处理这个问题(我假设这些都是单词)。
from bisect import bisect_left
f = open('myfile.csv')
words = []
for line in f:
words.extend(line.strip().split(','))
wordtofind = 'bacon'
ind = bisect_left(words,wordtofind)
if words[ind] == wordtofind:
print '%s was found!' % wordtofind
从文件中加载所有的值可能需要一点时间。这段代码使用二分查找来找到你的单词。在这个例子中,我在找“培根”(谁不想找培根呢?)。如果有重复的值,你可能还想用 bisect_right 来找到比你要找的值右边最靠近的那个位置的索引。如果你有键值对,也可以使用这个方法。你只需要把你的单词列表中的每个对象变成一个包含 [键, 值] 的列表。
附注
我觉得在 CSV 文件中逐行读取数据并不容易。你看,这些文件基本上就是长长的字符串,其中的 \n 字符表示换行。
4
你可以使用内存映射来处理非常大的文件。
import mmap,os,re
reportFile = open( "big_file" )
length = os.fstat( reportFile.fileno() ).st_size
try:
mapping = mmap.mmap( reportFile.fileno(), length, mmap.MAP_PRIVATE, mmap.PROT_READ )
except AttributeError:
mapping = mmap.mmap( reportFile.fileno(), 0, None, mmap.ACCESS_READ )
data = mapping.read(length)
pat =re.compile("b.+",re.M|re.DOTALL) # compile your pattern here.
print pat.findall(data)
7
如果你的csv文件没有变化,可以把它加载到一个数据库里,这样查找起来会又快又方便。不过,如果你对SQL不太了解,可能需要先学习一下。
下面是一个简单的例子,演示如何把csv文件的数据插入到sqlite表中。这个例子中的csv文件是用';'来分隔的,并且有两列。
import csv
import sqlite3
con = sqlite3.Connection('newdb.sqlite')
cur = con.cursor()
cur.execute('CREATE TABLE "stuff" ("one" varchar(12), "two" varchar(12));')
f = open('stuff.csv')
csv_reader = csv.reader(f, delimiter=';')
cur.executemany('INSERT INTO stuff VALUES (?, ?)', csv_reader)
cur.close()
con.commit()
con.close()
f.close()