Подтвердить что ты не робот

Самый эффективный способ синтаксического анализа большого .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, но пока не могу быть уверен. Любые предложения и советы, прежде чем я начну внедрять? Большое спасибо!

4b9b3361

Ответ 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 - это разбор строк (не то же самое, что и строки!) Полей.

Вам действительно нужно создать список в памяти всех строк?