Об обработке CSV файлов
О том, как читать и разбирать CSV-файлы различными методами (с помощью языков C#, Python, средствами MS Excel или MS SQL Server) написано и сказано достаточно, но нам хотелось бы поделиться личным опытом обработки больших объёмов в формате CSV.
Не так давно перед нами стояла задача обработки данных из двух автоматизированных систем, в виде 11-ти файлов средним размером около 3 ГБ (в нашем случае это было ~3000000 строк) и одного файла ~36 ГБ (~242000000 строк).
Суть обработки заключалась в внутреннем соединении файлов (inner join). Вариант с использованием SQL-сервера сразу отпал, так как загрузка таких объёмов занимает значительное время и высока вероятность ошибок, возникающих в процессе импорта. Использование датафреймов (DataFrame) библиотеки Pandas физически невозможно в обычном виде: объём оперативной памяти 16 ГБ, объём данных загружаемых в память 39 ГБ. Тут всё очевидно.
Изначально нами было принято решение в цикле по 11-ти файлам читать их построчно и читать по каждой строке в цикле большой файл:
В целом, вариант рабочий, но есть некоторые нюансы. Главная проблема такого подхода заключается во времени работы, ведь для реализации алгоритма должно пройти 11*3 000 000 * 242 000 000 итераций цикла, при этом в каждой итерации происходит выполнение функции разбиения текста (split). Так же, стоит отметить, что в каждой из 3 000 000 итераций происходит открытия файла в 242 000 000 строк. Обратный вариант однократного открытия файлов и чтения внутри него файлов по 3 000 000 строк также является неприемлемым для поставленной задачи. Решить вопрос с комфортным временем выполнения и сравнительно не сложным алгоритмом нам удалось при помощи библиотеки Pandas.
Сначала мы этот вариант «отбросили», но потом вспомнили, что функция read_csv имеет пару интересных и полезных параметров. Параметры эти nrows и skiprows, т.е. количество загружаемых и пропускаемых строк соответственно. Использование этих параметров позволило читать объёмный файл поблочно и «сталкивать» его с цельным файлом поменьше. Вот код такого решения:
Таким образом нам удалось в приемлемые сроки получить необходимую выборку, не нагружая оперативную память. В процессе работы скрипта использование памяти колебалось от 35 до 54 процентов.
В заключение следует сказать, что сей метод далеко не панацея и подходит он далеко не во всех случаях, как, впрочем, и все алгоритмы на свете. Ведь любой инструмент нужно использовать с умом, чтобы он оправдал оджидания.
Попробуйте ImportExportDataSql, которая сможет загрузить большие csv файлы в Sql Server. Можно настроить поля, например, выбрать только ключевые поля и загрузить их в базу, потом сделать джойн в базе
ImportExportDataSql загружает Csv файл в базу порциями, чтобы память не переполнялась. Данные в базу загружаются очень быстро, так как используется класс SqlBulkInsert
Спасибо!
Python сила
Согласны!