从big csv创建字典列表

时间:2015-11-25 14:56:43

标签: python csv dictionary generator avro

我有一个非常大的csv文件(10 gb),我想阅读它并创建一个字典列表,其中每个字典代表csv中的一行。 像

这样的东西
@Override
public void onDestroy() {
   LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
   locationManager.removeUpdates(locationListener);

   NotificationManager mNotificationManager =
                    (NotificationManager) getSystemService(
                            Context.NOTIFICATION_SERVICE);
   mNotificationManager.cancel(1);
}

我正在尝试使用生成器来实现它以避免任何内存问题,我目前的代码如下:

[{'value1': '20150302', 'value2': '20150225','value3': '5', 'IS_SHOP': '1', 'value4': '0', 'value5': 'GA321D01H-K12'},
{'value1': '20150302', 'value2': '20150225', 'value3': '1', 'value4': '0', 'value5': '1', 'value6': 'GA321D01H-K12'}]

问题是,由于列表变得太大而且进程被终止,基本上它会耗尽内存。 有没有办法以有效的方式达到相同的结果(dictonaries列表)?我对发电机/产量很新,所以我甚至不知道我是否正确使用它。

我也尝试过使用pypy的虚拟环境但是内存中断了(不过一会儿)。

基本上我想要一个字典列表的原因是我想尝试使用fastavro将csv转换为avro格式,因此任何有关如何使用fastavro(https://pypi.python.org/pypi/fastavro)而不创建字典列表的提示都会不胜感激

1 个答案:

答案 0 :(得分:3)

如果目标是从csv转换为avro,则没有理由存储输入值的完整列表。那就是打败了使用发电机的全部目的。在设置架构后,它看起来像fastavro's writer is designed to take an iterable and write it out one record at a time,因此您可以直接将其传递给生成器。例如,您的代码将省略创建list的步骤(侧注:命名变量list是一个坏主意,因为它会影响/踩踏内置名称list),并直接写出发电机:

from fastavro import writer

def csv_reader():
    with open('export.csv') as f:
        reader = csv.DictReader(f)
        for row in reader:
            yield row

    # If this is Python 3.3+, you could simplify further to just:
    with open('export.csv') as f:
        yield from csv.DictReader(f)

# schema could be from the keys of the first row which gets manually written
# or you can provide an explicit schema with documentation for each field
schema = {...}  

with open('export.avro', 'wb') as out:
    writer(out, schema, csv_reader())

然后,生成器一次生成一行,writer一次写入一行。写入后丢弃输入行,因此内存使用量保持最小。

如果您需要修改行,请在row之前修改csv_reader生成器中的yield