2010-02-19 77 views
3

我正在用Python读取600万条.csv文件,并且我希望能够通过此文件搜索特定条目。如何通过Python中的.csv文件快速搜索

是否有任何技巧来搜索整个文件?你应该把整个东西都读成字典吗?还是每次都要进行搜索?我试着将它加载到字典中,但这花了很长时间,所以我每次都在搜索整个文件,这看起来很浪费。

我可以利用列表按字母顺序排列吗? (例如,如果搜索词以“b”开头,则仅从包含以“b”开始的第一个词的行到包括以“b”开头的最后一个词的行)搜索

我正在使用import csv

(侧面的问题:它有可能使csv去一个特定的行文件中我想使程序开始在随机线)

编辑:我已经有了的副本列表作为一个.sql文件,我怎么能实现它到Python?

+5

我会先将文件导入数据库。 – Seth 2010-02-19 21:06:07

+0

我忘了提及我不是一个Python专家,所以我们将不胜感激代码示例。 – 2010-02-19 21:12:02

+0

每次运行脚本时,您会执行多少次查找? – 2010-02-19 23:23:22

回答

6

如果csv文件没有更改,请将其加载到数据库中,在该数据库中搜索快速且容易。如果你不熟悉SQL,那么你需要重新学习一下。

下面是从csv插入到sqlite表的粗略示例。示例csv是';'分隔,并有2列。

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() 
+0

我曾经希望我不用SQL来做到这一点,Python应该几乎和Perl处理字符串一样快? SQL真的更快吗? ()我想使用Linux,所以请尝试建议使用跨平台软件 – 2010-02-19 21:51:17

+0

com.close()应该是con.close() – pwdyson 2010-02-19 21:51:39

+2

@Baldur - 这不是perl vs python的问题,你的问题是你正在反复阅读一个大文件。 Perl和python会以同样的方式做到这一点。数据库只是为您提供更好的索引和搜索界面。 – JimB 2010-02-19 21:59:01

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查找等于您要搜索的值的最右侧元素之外的索引1。如果您有键:值对,您仍然可以使用它。你只需要让你的单词列表中的每个对象都是[键,值]的列表。

旁注

我不认为你可以真正从线走在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) 
1

您不能直接转到特定行的文件,因为行是可变长度,所以唯一的办法知道线#N时首先是搜索前n个换行符。它是不够的,只认准“\ n”字符,因为CSV允许换行表格单元格,所以你真的有反正来解析文件。

0

我的想法是使用Python ZODB模块存储dictionaty类型的数据,然后使用该数据结构创建新的CSV文件。当时做你所有的手术。

0

有一个相当简单的方式来做到这一点。根据你想要打印多少列,你可能需要添加或删除一些打印行。

import csv 
search=input('Enter string to search: ') 
stock=open ('FileName.csv', 'wb') 
reader=csv.reader(FileName) 
for row in reader: 
    for field in row: 
     if field==code: 
      print('Record found! \n') 
      print(row[0]) 
      print(row[1]) 
      print(row[2]) 

我希望这个设法帮助。