Самый эффективный способ синтаксического анализа большого .csv в python?
Я попытался посмотреть другие ответы, но я по-прежнему не уверен, как правильно это сделать.
У меня есть несколько действительно больших файлов .csv(может быть гигабайт каждый), и я хочу сначала получить их метки столбцов, потому что они не все одинаковы, а затем, согласно предпочтениям пользователя, извлеките некоторые из этих столбцов с некоторыми критериями,
Прежде чем начать часть извлечения, я сделал простой тест, чтобы узнать, что является самым быстрым способом анализа этих файлов, и вот мой код:
def mmapUsage():
start=time.time()
with open("csvSample.csv", "r+b") as f:
# memory-mapInput the file, size 0 means whole file
mapInput = mmap.mmap(f.fileno(), 0)
# read content via standard file methods
L=list()
for s in iter(mapInput.readline, ""):
L.append(s)
print "List length: " ,len(L)
#print "Sample element: ",L[1]
mapInput.close()
end=time.time()
print "Time for completion",end-start
def fileopenUsage():
start=time.time()
fileInput=open("csvSample.csv")
M=list()
for s in fileInput:
M.append(s)
print "List length: ",len(M)
#print "Sample element: ",M[1]
fileInput.close()
end=time.time()
print "Time for completion",end-start
def readAsCsv():
X=list()
start=time.time()
spamReader = csv.reader(open('csvSample.csv', 'rb'))
for row in spamReader:
X.append(row)
print "List length: ",len(X)
#print "Sample element: ",X[1]
end=time.time()
print "Time for completion",end-start
И мои результаты:
=======================
Populating list from Mmap
List length: 1181220
Time for completion 0.592000007629
=======================
Populating list from Fileopen
List length: 1181220
Time for completion 0.833999872208
=======================
Populating list by csv library
List length: 1181220
Time for completion 5.06700015068
Итак, кажется, что библиотека csv, которую большинство людей использует, действительно намного медленнее, чем другие.
Возможно, позже это будет быстрее, когда я начну извлекать данные из файла csv, но пока не могу быть уверен.
Любые предложения и советы, прежде чем я начну внедрять?
Большое спасибо!
Ответы
Ответ 1
Как уже отмечалось несколько раз, первые два метода не выполняют фактический разбор строк, они просто читают строку за раз без извлечения полей. Я полагаю, что большая часть разницы в скорости, наблюдаемой в CSV, связана с этим.
Модуль CSV неоценим, если вы включаете любые текстовые данные, которые могут включать в себя больше "стандартного" синтаксиса CSV, чем просто запятые, особенно если вы читаете из формата Excel.
Если у вас есть только строки типа "1,2,3,4", вы, вероятно, подойдете к простому разбиению, но если у вас есть строки типа "1,2,'Hello, my name\ fred'"
вы собираюсь сходить с ума, пытаясь разобрать это без ошибок.
CSV также будет прозрачно обрабатывать такие вещи, как переводы строк в середине строки в кавычках. Простое for..in
без CSV будет иметь проблемы с этим.
Модуль CSV всегда работал нормально для меня, читая Unicode-строки, если я использую его так:
f = csv.reader(codecs.open(filename, 'rU'))
Он достаточно надежен для импорта многотысячных файлов строк с Юникодом, строк в кавычках, строк новой строки в середине строк в кавычках, строк с пропущенными в конце полями и т.д. С разумным временем чтения.
Я бы попробовал использовать его в первую очередь и искать оптимизацию только в том случае, если вам действительно нужна дополнительная скорость.
Ответ 2
Сколько вы заботитесь о санитации?
Модуль csv
действительно хорош в понимании разных диалектов csv файлов и обеспечения того, что экранирование происходит нормально, но это определенно переполняет и может часто бывает больше проблем, чем это стоит (особенно если у вас есть юникод!)
На самом деле наивная реализация, которая успешно проходит \,
, будет:
import re
def read_csv_naive():
with open(<file_str>, 'r') as file_obj:
return [re.split('[^\\],', x) for x in file_obj.splitlines()]
Если ваши данные просты, это будет отлично работать. Если у вас есть данные, которые могут потребовать больше экранов, csv
, вероятно, самая стабильная ставка.
Ответ 3
Чтобы прочитать большой файл csv, мы должны создать дочерний процесс для чтения кусков файла. Откройте файл, чтобы получить объект ресурса файла. Создайте дочерний процесс с ресурсом в качестве аргумента. Прочитайте набор строк как фрагмент. Повторите вышеуказанные 3 шага, пока не достигнете конца файла.
from multiprocessing import Process
def child_process(name):
# Do the Read and Process stuff here.if __name__ == '__main__':
# Get file object resource.
.....
p = Process(target=child_process, args=(resource,))
p.start()
p.join()
Для кода перейдите по этой ссылке. Это поможет вам.
http://besttechlab.wordpress.com/2013/12/14/read-csv-file-in-python/
Ответ 4
Ваши первые 2 метода НЕ анализируют каждую строку в полях. Способ csv
- это разбор строк (не то же самое, что и строки!) Полей.
Вам действительно нужно создать список в памяти всех строк?