我希望尽可能快地使用Python:
我的第一个代码是以下循环(i to j)
:
with open('Train.csv', 'rt') as f:
row = next(itertools.islice(csv.reader(f), row_number, row_number+1))
tags = (row[3].decode('utf8'))
return tags
但我上面的代码一次读取一列csv并且速度很慢。
如何在一次调用中读取所有行并快速连接?
编辑以获取更多信息:
csv文件大小为7GB;在Windows XP上我只有4GB的RAM;但我不需要阅读所有专栏(我认为只有1%的7GB会很好)。
答案 0 :(得分:2)
如果文件不是HUGE(百兆字节)而你实际上需要读取很多行,那么可能只是
tags = " ".join(x.split("\t")[3]
for x in open("Train.csv").readlines()[from_row:to_row+1])
将是最快的方式。
如果文件非常大,那么你唯一可以做的就是遍历所有行,因为很遗憾地使用CSV(通常)可变大小的记录。
如果特定的CSV偶然使用固定大小的记录格式(对于大文件来说并不罕见),那么直接搜索到该文件可能是一种选择。
如果文件使用可变大小的记录,并且搜索必须使用不同的范围进行多次,那么只创建一次简单的外部索引(例如,对于1000的倍数的所有行号,行 - >文件偏移量)可以好主意。
答案 1 :(得分:1)
由于我知道您感兴趣的数据,我可以从经验中说出:
import csv
with open('Train.csv', 'rt') as csvfile:
reader = csv.reader(csvfile, delimiter=' ', quotechar='|')
for row in reader:
row[0] # ID
row[1] # title
row[2] # body
row[3] # tags
您当然可以每行选择您想要的任何内容,并根据需要进行存储。
通过使用迭代器变量,您可以决定要收集哪些行:
import csv
with open('Train.csv', 'rt') as csvfile:
reader = csv.reader(csvfile, delimiter=' ', quotechar='|')
linenum = 0
tags = [] # you can preallocate memory to this list if you want though.
for row in reader:
if linenum > 1000 and linenum < 2000:
tags.append(row[3]) # tags
if linenum == 2000:
break # so it won't read the next 3 million rows
linenum += 1
关于它的好处还在于,当你逐行阅读时,这将真正使用低内存。
如上所述,如果你想要后面的情况,它仍然需要解析数据才能到达那里(由于文本中有新行,这是不可避免的,所以你不能跳到某一行)。就个人而言,我只是粗略地使用了linux的split
,将文件拆分成块,然后对它们进行编辑,确保它们以ID开头(并以标签结尾)。
然后我用了:
train = pandas.io.parsers.read_csv(file, quotechar="\"")
快速阅读拆分文件。
答案 2 :(得分:1)
您的问题未包含足够的信息,可能是因为您没有看到一些现有的复杂性:大多数CSV文件每行包含一条记录。在这种情况下,跳过你不感兴趣的行很简单。但是在CSV记录中可以跨行,因此一般解决方案(如标准库中的CSV阅读器)必须解析记录以跳过行。您可以自行决定用例中的优化是什么。
下一个问题是,您不知道,您发布的代码的哪一部分太慢了。测量它。您的代码永远不会比从光盘读取文件所需的时间更快。你检查过了吗?或者你猜到哪个部分会变慢?
如果你想快速转换适合内存的CSV数据,我建议使用/ learn Pandas。因此,分两步拆分代码可能是个好主意:
答案 3 :(得分:0)
sed是为任务'读取csv文件'的行i到j而设计的.to
如果解决方案不一定是纯Python,我认为使用sed sed -n 'i, jp'
预处理csv文件,然后使用Python解析输出将简单快捷。