从非常大的csv数据中有效地创建字典字典

时间:2013-05-10 00:15:39

标签: python dictionary mapreduce

我在逗号分隔文件中按日期和时间分割了不同位置的数据。位置201682的示例如下所示:

Location    Date        Time            Data
201682      3/15/2011   1:00:00 AM      10
201682      3/16/2011   1:00:00 AM      12
201682      3/15/2011   2:00:00 AM      32
201682      3/16/2011   2:00:00 AM      31
201682      3/15/2011   3:00:00 AM      21
201682      3/16/2011   3:00:00 AM      20
201682      3/15/2011   4:00:00 AM      45
201682      3/16/2011   4:00:00 AM      56
201682      3/15/2011   5:00:00 AM      211
201682      3/16/2011   5:00:00 AM      198
201682      3/15/2011   6:00:00 AM      512
201682      3/16/2011   6:00:00 AM      324

我运行的文件包含数百万行数据。为了处理数据,我试图在Python中创建一个字典对象。它基本上将位置用作键,并将其余数据存储在列表中。这是我(徒劳)的尝试:

import csv

headers = None
records = {}

reader=csv.reader(open(csvFile))
for row in reader:
    if reader.line_num == 1:
        headers = row[1:]
    else:
        records[row[0]] = dict(zip(headers, row[1:]))

print records['201682']

我得到的输出如下所示:

{'Date':'3/16/2011', 'Time':'6:00:00 AM', 'Data':'324'}

我希望数据看起来像这样:

{['Date':'3/15/2011', 'Time':'1:00:00 AM', 'Data':'10'],
 ['Date':'3/16/2011', 'Time':'1:00:00 AM', 'Data':'12'],
 ['Date':'3/15/2011', 'Time':'2:00:00 AM', 'Data':'32'],
 ['Date':'3/16/2011', 'Time':'2:00:00 AM', 'Data':'31'],
 ['Date':'3/15/2011', 'Time':'3:00:00 AM', 'Data':'21'],
 ['Date':'3/16/2011', 'Time':'3:00:00 AM', 'Data':'20'],
 ['Date':'3/15/2011', 'Time':'4:00:00 AM', 'Data':'45'],
 ['Date':'3/16/2011', 'Time':'4:00:00 AM', 'Data':'56'],
 ['Date':'3/15/2011', 'Time':'5:00:00 AM', 'Data':'211'],
 ['Date':'3/16/2011', 'Time':'5:00:00 AM', 'Data':'198'],
 ['Date':'3/15/2011', 'Time':'6:00:00 AM', 'Data':'512'],
 ['Date':'3/16/2011', 'Time':'6:00:00 AM', 'Data':'324']}

目的是为字典中的每条记录存储DateTimeData信息。然后将列表中特定位置的所有数据混为一谈。最后,创建一个以位置为键的列表。

如何获取代码来执行此操作?另外,有更有效的方法吗?我的数据文件大小接近24GB。 [Python中是否存在针对多个线程的map-reduce方法 - 我对map reduce范例非常陌生...]。非常感谢!

1 个答案:

答案 0 :(得分:2)

您描述的目标是最终得到一个数据结构。但是,大多数数据结构都是为查询提供服务 - 您究竟要从这些信息中提取什么?在不知情的情况下,很难说什么是最有效的,或者map-reduce是否会有所帮助。

那就是说,最简单的做法是建立你所描述的包含行ID而不是行数据本身的字典。这肯定会节省一些空间,仍然允许您回答您的疑问。但是,如果您的数据在磁盘上设置为24GB,那么您需要更多数据才能将其保存在RAM中。假设给定一个查询,获取行ID就足够了,我建议:

import csv

headers = None
records = {}

reader = csv.reader(open(csvFile))

# So we can have lists as entries by default
from collections import defaultdict
index = {}

for row in reader:
    if reader.line_num == 1:
        headers = row
        # We'll set up rows to be a dictionary with one defaultdict
        # for each of the headers, mapping the unique values to the
        # rows that match
        index = dict((header, defaultdict(list)) for header in headers)
    else:
        for header, value in zip(headers, row):
            index[header][value].append(reader.line_num)

# Now, you can find out which rows have, say, 'Location' set to a given value
index['Location']['201682']

# Or all the rows with 'Time' set to '1:00:00 AM'
index['Time']['1:00:00 AM']

也就是说,这只是使用python词典来构建索引,并且有更适合这种工具的工具。我想起了mySQL,特别是如果你要进行大量的即席查询。它可能支持比字典提供更好的索引,并且不会受到必须适应内存的限制。