Python: быстрый и эффективный способ записи большого текстового файла

У меня есть вопрос, связанный со скоростью/эффективностью, о python:

Мне нужно написать большое количество очень больших файлов данных R, размером около 0,5-2 ГБ. По сути, это большая таблица, разделенная табуляцией, где каждая строка может содержать числа с плавающей запятой, целые числа и строки.

Обычно я просто помещал все свои данные в пустой фрейм данных и использовал np.savetxt для их сохранения, но, поскольку существуют разные типы данных, их нельзя поместить в один массив.

Поэтому я прибегал к простой сборке строк вручную, но это немного медленно. Пока делаю:

1) Собрать каждую строку как строку 2) Объединить все строки в одну огромную строку 3) Записать строку в файл

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

Итак, мой вопрос: что такое хорошая рутина для такого рода проблем? Тот, который уравновешивает скорость и потребление памяти для наиболее эффективной конкатенации строк и записи на диск.

... а может быть, эта стратегия просто плохая и я должен сделать что-то совсем другое?

Заранее спасибо!


person Misconstruction    schedule 25.02.2014    source источник
comment
Почему бы вам просто не записать каждый бит данных в файл так, как он у вас есть. Не похоже, что есть необходимость объединять все эти строки. Записи будут автоматически буферизоваться на пути к диску.   -  person Michael Mior    schedule 26.02.2014
comment
Просто кажется, что скорость значительно снижается, когда file.write вызывается несколько раз, а не один раз, но, может быть, я ошибаюсь?   -  person Misconstruction    schedule 26.02.2014
comment
Если вы не опубликуете свой код, мало кто сможет помочь.   -  person Michael Mior    schedule 26.02.2014


Ответы (3)


Похоже, Pandas может быть хорошим инструментом для решения этой проблемы. Начать работать с pandas довольно просто, и он хорошо справляется с большинством способов, которыми вам может понадобиться получить данные в python. Панды хорошо справляются со смешанными данными (число с плавающей запятой, целое число, строки) и обычно могут определять типы самостоятельно.

Если у вас есть (R-подобный) фрейм данных в pandas, довольно просто вывести фрейм в csv.

DataFrame.to_csv(path_or_buf, sep='\t')

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

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_csv.html

person Joan Smith    schedule 25.02.2014
comment
Я никогда не пробовал использовать Pandas, поэтому дам его назад. Однако в некоторых случаях фактический текстовый файл будет немного более запутанным, чем фрейм данных. - person Misconstruction; 26.02.2014
comment
@Misconstruction, если это ответило на ваш вопрос, отметьте ответ галочкой. - person Joan Smith; 05.03.2014

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

Буферизация Python отличается от буферизации ОС, и вы можете указать, как вы хотите буферизовать данные, установив для аргумента buffering значение open.

person Clarus    schedule 25.02.2014
comment
Как вы можете установить аргументы буферизации? - person Misconstruction; 26.02.2014
comment
open(foo, wb, 1024) установит буфер размером 1 КБ. 0 и 1 имеют особое значение. - person Clarus; 26.02.2014
comment
Вам действительно не нужно устанавливать размер буферов вручную. Значения по умолчанию работают хорошо большую часть времени. - person Michael Mior; 26.02.2014

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

http://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html

person Ron    schedule 25.02.2014