Вопрос по python, sorting – Как сортировать огромные файлы с помощью Python?
Я нашел этот многообещающий код на activestate.com для сортировки огромных файлов. Я пытаюсь запустить его на интерпретаторе Python 2.6.5 по умолчанию в Ubuntu 10.04. Когда я пытаюсь запустить его на небольшом тестовом файле, я получаю трассировку ошибок ниже. Я просил о помощи на activestate.com, но эта тема молчала уже более 18 месяцев. Здесь есть кто-нибудь, кто видит очевидное решение?
Благодарю.
## {{{ http://code.activestate.com/recipes/576755/ (r3)
# based on Recipe 466302: Sorting big files the Python 2.4 way
# by Nicolas Lehuen
import os
from tempfile import gettempdir
from itertools import islice, cycle
from collections import namedtuple
import heapq
Keyed = namedtuple("Keyed", ["key", "obj"])
def merge(key=None, *iterables):
# based on code posted by Scott David Daniels in c.l.p.
# http://groups.google.com/group/comp.lang.python/msg/484f01f1ea3c832d
if key is None:
keyed_iterables = iterables
else:
keyed_iterables = [(Keyed(key(obj), obj) for obj in iterable)
for iterable in iterables]
for element in heapq.merge(*keyed_iterables):
yield element.obj
def batch_sort(input, output, key=None, buffer_size=32000, tempdirs=None):
if tempdirs is None:
tempdirs = []
if not tempdirs:
tempdirs.append(gettempdir())
chunks = []
try:
with open(input,'rb',64*1024) as input_file:
input_iterator = iter(input_file)
for tempdir in cycle(tempdirs):
current_chunk = list(islice(input_iterator,buffer_size))
if not current_chunk:
break
current_chunk.sort(key=key)
output_chunk = open(os.path.join(tempdir,'%06i'%len(chunks)),'w+b',64*1024)
chunks.append(output_chunk)
output_chunk.writelines(current_chunk)
output_chunk.flush()
output_chunk.seek(0)
with open(output,'wb',64*1024) as output_file:
output_file.writelines(merge(key, *chunks))
finally:
for chunk in chunks:
try:
chunk.close()
os.remove(chunk.name)
except Exception:
pass
Трассировка ошибок:
Traceback (most recent call last):
File "./batch_sort.py", line 108, in <module>
batch_sort(args[0],args[1],options.key,options.buffer_size,options.tempdirs)
File "./batch_sort.py", line 54, in batch_sort
output_file.writelines(merge(key, *chunks))
File "./batch_sort.py", line 30, in merge
yield element.obj
AttributeError: 'str' object has no attribute 'obj'
Вам непонятно, что такое "огромный" означает, так что я буду понимать, что это означает «огромный». Если вы действительно сортируете огромные файлы, вы, вероятно, не хотите использовать Python для этого. Его интерпретирующая природа в сочетании с динамическим распределением памяти, вероятно, сделает его медленным. Найдите отдельную утилиту для сортировки; они предназначены для максимально быстрой сортировки больших объемов данных.
Ira Baxter
Хороший вопрос. Я определяю "огромный" как файл UTF-8 с 14 миллионами или более строками, каждая строка в среднем составляет 175 символов, что составляет от 2,5 до 7,5 ГБ (многие файлы имеют все 3-байтовые символы UTF-8). Альтернативы используют сортировку Linux из скрипта / терминала bash. Производительность старой версии этого кода в порядке, но это должно быть быстрее.
tahoar
1
ответ
Если вы не предоставите ключ, каждый элемент является строкой, а не кортежем с ключом.
Попробуйте это вместо:
def merge(key=None, *iterables):
# based on code posted by Scott David Daniels in c.l.p.
# http://groups.google.com/group/comp.lang.python/msg/484f01f1ea3c832d
if key is None:
for element in heapq.merge(*iterables):
yield element
else:
keyed_iterables = [(Keyed(key(obj), obj) for obj in iterable)
for iterable in iterables]
for element in heapq.merge(*keyed_iterables):
yield element.obj
@tahoar Я использую тот же скрипт для сортировки огромного файла. При запуске я получаю сообщение об ошибке в строке 51 с open (output, 'wb', 64 * 1024) в качестве output_file: output_file.writelines (merge (key, * chunks)) valueerror: операция ввода-вывода для закрытого файла. Вы видели эту ошибку? Сортировка отлично работает для небольшого файла, хотя!
@ Думаю, правда в том, что я отказался от этих усилий. Я сталкивался с новыми проблемами каждый раз, когда достигал больших размеров файлов. Поскольку мне нужна только эта функциональность в Linux, мое окончательное решение использует Python subprocess.Popen () для вызова Linux & quot; sort & quot; приложение и все мои проблемы исчезли. Извините, я не могу помочь дальше.
tahoar
Похожие вопросы
Вам непонятно, что такое "огромный" означает, так что я буду понимать, что это означает «огромный». Если вы действительно сортируете огромные файлы, вы, вероятно, не хотите использовать Python для этого. Его интерпретирующая природа в сочетании с динамическим распределением памяти, вероятно, сделает его медленным. Найдите отдельную утилиту для сортировки; они предназначены для максимально быстрой сортировки больших объемов данных.
Хороший вопрос. Я определяю "огромный" как файл UTF-8 с 14 миллионами или более строками, каждая строка в среднем составляет 175 символов, что составляет от 2,5 до 7,5 ГБ (многие файлы имеют все 3-байтовые символы UTF-8). Альтернативы используют сортировку Linux из скрипта / терминала bash. Производительность старой версии этого кода в порядке, но это должно быть быстрее.