Как лучше обрабатывать данные из .txt файла в python?

Рейтинг: 4Ответов: 1Опубликовано: 21.05.2023

Ситуация следующая: есть достаточно большой текстовый файл (порядка миллиона длинных строк), нужно его распарсить.
Если важна конкретика: достать координаты точек, т.е. в результате получается двумерный массив, каждый элемент которого это x,y,z.

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

К сути дела. Как лучше поступить с точки зрения скорости и памяти (да и в целом, что является в данном случае хорошей практикой):

  1. Открыть файл, прочитать одну точку из него, и для нее сразу же, не закрывая файл и не продолжая считывание, производить действия описанные выше (т.е. пробег по еще одному массиву, математические операции). И так для каждой точки (т.е. файл висит открытым на протяжении работы всего алгоритма).

  2. Достать из файла двумерный массив точек. Закрыть файл. И уже потом делать с каждой точкой из этого массива вышеуказанные действия.

Очень прошу подробного ответа, важно быстродействие кода.

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

Если ни один из двух вариантов не кажется хорошим, предложите свой.
Заранее спасибо.

Ответы

▲ 1Принят

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

def read_file(path: str):  # Пример построчного чтения файла на примере гениратора
    with open(path, "r") as file:
        for line in file:
            yield line

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

Выбор третьего из двух вам предложили в комментариях - использовать другие типы файлов вроде csv, pickle и им подобных. На счёт производительности ничего конкретно сказать не могу, ибо не замерял, могу только предположить: в csv данные структурированы, и для чтения их средствами python может занять немного больше времени чем чтение текстового файла (без учёта того, что вы также выполняете парсинг данных). Но если учитывать, что вы можете использовать специализированные библиотеки, таких как pandas, для чтения данных из файлов CSV может быть более эффективным и удобным, чем чтение данных из текстового файла. Как итог если предположить, что этот метод лучше первых двух по производительности, он всё равно имеет один важный недочёт, данные сначала надо конвертировать из txt в csv (или другой формат), что требует лишних действий и времени.

На крайняк можно после чтения каждой строки закрывать файл, при этом запоминая текущую позицию, а после снова открывать файл и перепрыгивать на нужную позицию методом .seek(). Но я этого не советую, ибо будет тратиться время ещё и на на открытие/закрытие файла.

И всё же всё индивидуально. 1М строк это не так и много в нашем времени, поэтому можно использовать любой из методов, при учёте что у вас всё-таки достаточно ОЗУ :)