2015-11-25 3 views
1

У меня очень большой файл csv (10 gb), и я бы хотел его прочитать и создать список словарей, где каждый словарь представляет собой строку в csv. Что-то вродеСоздание списка словарей из больших csv

[{'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'}] 

Я пытаюсь добиться этого с помощью генератора, чтобы избежать каких-либо воспоминаний вопросы, мой текущий код выглядит следующим образом:

def csv_reader(): 
    with open('export.csv') as f: 
     reader = csv.DictReader(f) 
     for row in reader: 
      yield {key: value for key, value in row.items()} 

generator = csv_reader() 
list = [] 
for i in generator: 
    list.append(i) 

Проблема заключается в том, что в основном это закончится из-за того, что список становится слишком большим, и процесс убит. Есть ли способ добиться того же результата (список подкатегорий) эффективным способом? Я очень новичок в генераторах/уроках, поэтому я даже не знаю, правильно ли я их использую.

Я также попытался использовать виртуальную среду с pypy, но память все равно сломается (чуть позже).

В основном причина, почему я хочу список словарей, что я хочу, чтобы попытаться преобразовать CSV в Avro формат, используя fastavro поэтому любые намеки на то, как с помощью fastavro (https://pypi.python.org/pypi/fastavro) без создания списка словарей буду оценены

+1

Если вы сохраняете полные результаты работы генератора, вы не сохраняете память. Если цель состоит в том, чтобы обрабатывать файл по строкам, то обрабатывайте его по строкам, не храните его. Кроме того, обратите внимание: 'yield {key: value for key, value in row.items()}' - это просто мелкое копирование 'dict', когда у вас уже есть отличный« dict », просто введите' row row' непосредственно , – ShadowRanger

ответ

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 -в его.

+0

Спасибо, он работает. Теперь мне просто нужно понять, как использовать разные кодеки в fastavro: D – user2697881

Смежные вопросы