Различные способы чтения больших данных в Python - PullRequest
6 голосов
/ 09 декабря 2011

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

1.f=gzip.open(file,'r')
      for line in f:
          process line
     #how can I process nth line? can I?
2.f=gzip.open(file,'r').readlines()
  #f is a list
  f[10000]
  #we can process nth line

3.f=gzip.open(file,'r')
  while True:
       linelist=list(islice(f,4))

4.for line in fileinput.input():
  process line

В чем разница между 2 и 3?Я просто считаю, что их использование памяти одинаково.Функция islice () также должна сначала загрузить весь файл в память (но чуть позже по крупицам).И я слышал, что 4-й метод требует меньше памяти, он действительно обрабатывается по крупицам, верно?Для файла 10 ГБ какой метод чтения файлов вы бы порекомендовали?Любая мысль / информация приветствуется.thx

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

f1=open(inputfile1, 'r')
while True:
    line_group1 = list(islice(f1, 3))
    if not line_group1:
        break
    #then process specific lines say, the second line.
    processed 2nd line
    if ( ....):
           LIST1.append(line_group1[0])
           LIST1.append(processed 2nd line)
           LIST1.append(line_group1[2])

А потом че.вроде

with open(file,'r') as f,
    for line in f:
       # process line

может не работать, я прав?

Ответы [ 5 ]

5 голосов
/ 09 декабря 2011

Вы забыли -

with open(...) as f:
    for line in f:
        <do something with line>

Оператор with обрабатывает открытие и закрытие файла, в том числе, если во внутреннем блоке возникает исключение.for line in f рассматривает файловый объект f как итеративный, который автоматически использует буферизованный ввод-вывод и управление памятью, поэтому вам не нужно беспокоиться о больших файлах.

Оба 2,3 не рекомендуется для больших файловфайлы, поскольку они читают и загружают все содержимое файла в память перед началом обработки.Чтобы читать большие файлы, вам нужно найти способы, чтобы не читать весь файл за один раз.

Должен быть один - и желательно только один - очевидный способ сделать это.

5 голосов
/ 09 декабря 2011

Ознакомьтесь с выступлениями Дэвида М. Бизли о разборе больших файлов журналов с генераторами (презентацию см. В формате pdf):

http://www.dabeaz.com/generators/

1 голос
/ 09 декабря 2011

Вы можете использовать enumerate, чтобы получить индекс при выполнении итерации по чему-либо:

for idx, line in enumerate(f):
    # process line

Простая и эффективная память.На самом деле вы также можете использовать islice и выполнять итерацию по нему без предварительного преобразования в список:

for line in islice(f,start,stop):
    # process line

Ни один из подходов не будет считывать весь файл в память и создавать промежуточный список.

Что касается fileinput, это всего лишь вспомогательный класс для быстрого циклического перебора стандартного ввода или списка файлов, использование которого не дает преимущества по эффективности использования памяти.

Как указывает Срикар, использование with оператор является предпочтительным способом открыть / закрыть файл.

0 голосов
/ 09 декабря 2011

Для чтения определенных строк в больших файлах вы можете использовать библиотеку linecache .

0 голосов
/ 09 декабря 2011

вы не знаете, сколько строк, пока не прочитаете и не посчитаете, сколько \ n в нем.В 1 вы можете добавить перечисление, чтобы получить номер строки.

...