以下函数将CSV文件解析为字典列表,其中列表中的每个元素都是一个字典,其中的值由文件的标头索引(假定为第一行。)
这个函数非常慢,对于一个相对较小的文件(少于30,000行)需要大约6秒钟。
我怎样才能加快速度?
def csv2dictlist_raw(filename, delimiter='\t'):
f = open(filename)
header_line = f.readline().strip()
header_fields = header_line.split(delimiter)
dictlist = []
# convert data to list of dictionaries
for line in f:
values = map(tryEval, line.strip().split(delimiter))
dictline = dict(zip(header_fields, values))
dictlist.append(dictline)
return (dictlist, header_fields)
回应评论:
我知道有一个csv模块,我可以像这样使用它:
data = csv.DictReader(my_csvfile, delimiter=delimiter)
这要快得多。但是,问题在于它不会自动将显然浮点数和整数的内容转换为数字,而是将它们作为字符串。我该如何解决这个问题?
使用“Sniffer”类对我不起作用。当我在我的文件上尝试它时,我收到错误:
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/csv.py", line 180, in sniff
raise Error, "Could not determine delimiter"
Error: Could not determine delimiter
如果显而易见,我怎样才能让DictReader将字段解析为它们的类型?
感谢。
感谢。
答案 0 :(得分:3)
import ast
# find field types
for row in csv.DictReader(my_csvfile, delimiter=delimiter):
break
else:
assert 0, "no rows to process"
cast = {}
for k, v in row.iteritems():
for f in (int, float, ast.literal_eval):
try:
f(v)
cast[k] = f
break
except (ValueError, SyntaxError):
pass
else: # no suitable conversion
cast[k] = lambda x: x.decode(encoding)
# read data
my_csvfile.seek(0)
data = [dict((k.decode(encoding), cast[k](v)) for k, v in row.iteritems())
for row in csv.DictReader(my_csvfile, delimiter=delimiter)]
答案 1 :(得分:1)
我发现您的代码有几个问题:
你为什么需要dicts?密钥存储在每个dict实例中,这会耗尽内存消耗。
您真的需要将所有实例保留在内存中,还是可以选择使用yield
?
尝试转换每个值需要时间,在我的选项中没有任何意义。如果您的列的值为“abc”和“123”,则最后一个值应该是一个字符串。因此,列的类型应该是固定的,您应该明确转换。
即使您想使用转换逻辑:使用csv模块并在之后转换值。
答案 2 :(得分:1)
熊猫怎么样?
import pandas as pd
# load everything in
df = pd.read_table(filename)
# coerce strings to numeric
df = df.convert_objects(convert_numeric=True)