Подсчитать количество новых строк вне двойных кавычек в файле 30GB + CSV в Python - PullRequest
3 голосов
/ 29 октября 2019

У меня есть большой файл (30GB +) CSV, где я подсчитываю количество новых строк, анализируя блок файла по блоку

Используя следующую функцию

def yieldblocks(file, size=1024*1024):
    while True:
        blocks = file.read(size)
        if not blocks: break
        yield blocks

И вызывая ее так,

sum(bl.count("\n") for bl in blocks(txtfile))

Я могу посчитать переводы строки чуть менее чем за час (я удивлен, что это лучшее, что я мог получить тоже)

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

Я пробовал описанное ниже, но оно не работает, и процесс завершается без результатов

sum(.5 if re.search('^[^"]*"(?=[^"]*(?:"[^"]*")*[^"]*$).*$', bl) else 1 for bl in yieldblocks(txtfile))

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

Я на 2 ГБ оперативной памяти, 32-разрядная ОС

Примечание: я пробовал модуль CSV, но его медленнее по сравнениючтобы считать по блокам и надеялся, что смогу как-то заставить это работать

Ответы [ 2 ]

1 голос
/ 29 октября 2019

Это может хорошо сработать для вас. pandas.read_csv обычно очень быстрый, но я не пробовал его по частям.

import pandas as pd
reader = pd.read_csv('file.csv', sep=',', chunksize=10000, low_memory=True)
line_count = sum(len(chunk) for chunk in reader)

В документации по немного больше (немного) информации .

0 голосов
/ 29 октября 2019

Самый простой и быстрый способ - использовать отображение памяти и перебирать байты следующим образом (псевдокод):

bool insidequotes = false

for each byte b:
  if b=='"'
    insidequotes = not insidequotes  // false -> true or true -> false

  else if b=='\n' and not insidequotes
    increment recordcount

Это не займет больше времени, чем требуется для копирования файлана диске (или даже просто прочитать файл) - не уверен насчет возможных издержек в Python.

Это также учитывает экранированные кавычки внутри полей:

123,test,"24"" monitor",456
...