эффективное чтение данных из огромного файла CSV

#python #csv

#python #csv

Вопрос:

Я пытался обработать свой огромный файл CSV (более 20 ГБ), но процесс был прерван при чтении всего файла CSV в память. Чтобы избежать этой проблемы, я пытаюсь прочитать второй столбец построчно.

Например, 2-й столбец содержит такие данные, как

  1. ххх, компьютер хорош
  2. ххх, алгоритм построения
     import collections
    
    wordcount = collections.Counter()
    
    with open('desc.csv', 'rb') as infile:
        for line in infile:
             wordcount.update(line.split())
     

Мой код работает для целых столбцов, как прочитать только второй столбец без использования CSV Reader?

Комментарии:

1. Вы могли бы использовать итерацию (для циклов / выхода) вместо загрузки большого количества данных в память. Я не знаю, насколько вы контролируете отдельные части, поэтому я не могу привести пример.

2. @DennisKuypers, спасибо. что вы подразумеваете под тем, сколько контроля?

3. Я имею в виду: можете ли вы изменить код или просто переносите результат из одной библиотеки в другую. Возможно, вы сможете использовать for something in descs: для перебора результатов один за другим. Вероятно , вам придется опустить .tolist() . Опять же, я не знаю библиотек, поэтому не могу подсказать вам правильный путь

4. @DennisKuypers Я изменил вопрос, вам это ясно?

Ответ №1:

Насколько я знаю, вызов csv.reader(infile) открывает и считывает весь файл…в этом и заключается ваша проблема.

Вы можете просто читать построчно и анализировать вручную:

 X=[]

with open('desc.csv', 'r') as infile:    
   for line in infile:
      # Split on comma first
      cols = [x.strip() for x in line.split(',')]

      # Grab 2nd "column"
      col2 = cols[1]

      # Split on spaces
      words = [x.strip() for x in col2.split(' ')]
      for word in words:     
         if word not in X:
            X.append(word)

for w in X:
   print w
 

Это позволит сохранить меньшую часть файла в памяти в данный момент времени (одна строка). Однако у вас все еще могут возникнуть проблемы с X увеличением переменной до довольно большого размера, так что программа выдаст ошибку из-за ограничений памяти. Зависит от того, сколько уникальных слов в вашем списке «словарный запас»

Комментарии:

1. Спасибо, но ваш пример работает только для первого столбца, верно? Если бы это был 3-й столбец, x.strip() был бы неправильным, правильно?

2. Извините, возможно, я неправильно понял, что вы имели в виду под столбцами. Я предположил, что «компьютер хорош» находится в отдельной строке, за которой следует «алгоритм сборки» в следующей строке. Где я использовал x.strip() / split() мог бы быть csv.reader() так же легко, если это работает для ваших входных файлов.

3. Спасибо, это работает. Поэтому не стоит использовать CSV Reader, когда файл слишком большой, верно?

Ответ №2:

Похоже, что код в вашем вопросе считывает файл 20G и разбивает каждую строку на разделенные пробелом токены, а затем создает счетчик, который ведет подсчет каждого уникального токена. Я бы сказал, что это то, куда уходит ваша память.

Из руководства csv.reader является итератором

объект reader, который будет перебирать строки в данном csv-файле. csvfile может быть любым объектом, который поддерживает протокол итератора и возвращает строку при каждом вызове его метода next()

так что можно перебирать огромный файл, используя csv.reader .

 import collections

wordcount = collections.Counter()

with open('desc.csv', 'rb') as infile:
    for row in csv.reader(infile):
        # count words in strings from second column
        wordcount.update(row[1].split())