Comments 30
- Собственно, можно обойтись и без костыля в виде (к тому же не бесплатного) vedit-а, который особо не автоматизируется, а требует нескольких десятков кликов вручную. Первая же ссылка в гугле по запросу
python xml splitter
выдает вот это. Если почитать код, понятно, что считывается в память и парсится оно чанками, а не все сразу. (Понятно, что наверняка есть еще куча других "резчиков", которые делают то же самое.) - Преобразование float64 во float32 и особенно int64 в uint8 может быть опасно по всем понятным причинам (потеря точности в первом случае и переполнение во втором). Нужно учитывать специфику данных.
+1
1. Очень помогло. Доработал код по вашей ссылке под python 3 и русские символы, которые он не читал — код.
Синтаксис сохранен:
2.Да, это вынужденная мера, чтобы освободить память. По значениям, которые встречаются в столбцах, это допустимо.
ps. vedit -30 дней бесплатно.
Синтаксис сохранен:
python xml-cut-chunk.py -o ./output/ -M 500000 big.xml
2.Да, это вынужденная мера, чтобы освободить память. По значениям, которые встречаются в столбцах, это допустимо.
ps. vedit -30 дней бесплатно.
0
чтобы обработать xml большого размера, совсем необязательно загружать его в память или пользоваться сторонними приложениями. мне тоже довелось работать с ФИАС, и я читал данные из файла XmlReader'ом (.net).
Примерно так:
В Python нет чего-то похожего?
Примерно так:
var reader = XmlReader.Create(xml);
while (!reader.EOF)
{
reader.Read();
...
}
В Python нет чего-то похожего?
+1
Когда читаешь подобный заголовок, надеешься, что будет что-то типа lxml.de/parsing.html#iterparse-and-iterwalk а тут XML2CSV и нет ответа как работать с большими XML при маленьком количестве оперативки. Это что, сезон курсовых на хабре опять? до нового года еще далеко.
Извините за снобизм
Извините за снобизм
0
Так файл не парсится целиком. Поэтому путь через разбиение и конвертацию.
Кроме того, после нее размеры файлов уменьшаются в разы.
Кроме того, после нее размеры файлов уменьшаются в разы.
0
Ну так вам и говорят, что это ручное разбиение и конвертация — это костыль, а не нормальное взрослое решение :) Вот для файла в всего 3 Гб работает, а что вы будете делать с файлом в 30 Гб? Файл и не надо парсить целиком, вон же ссылка выше про парсинг по частям (если структура позволяет).
0
Тогда тем более не ясна ваша ссылка на итераторы.
0
Для этого много лет назад придумали SAX-парсеры.
Можно читать XML не превращая его в объектную модель в памяти, а держать лишь маленький контекст, соответствующий максимум одной записи.
SAX-парсер устроен так, что в нём описывается код реакции на каждый элемент XML. Причем отдельно описывается реакция на открытие и закрытие каждого тега. Так на закрытие тега поля можно сохранять значение поля в буфферный словарик под соответствующим ключем, а на закрытие тега записи сохранять накопившийся словарик в CSV-файл в потоковом режиме дописывая в него строчку.
Так и террабайтные xml можно без мороки обрабатывать, лишь бы одна максимальная его запись в память помещалась. Думаю на гитхабе готовых SAX XML to CSV конвертеров валом. Ну или стоит сделать, если нет (хотя я сильно удивлюсь). Думаю код поместится на полтора экрана со всеми обработками ошибок и CLI.
Можно читать XML не превращая его в объектную модель в памяти, а держать лишь маленький контекст, соответствующий максимум одной записи.
SAX-парсер устроен так, что в нём описывается код реакции на каждый элемент XML. Причем отдельно описывается реакция на открытие и закрытие каждого тега. Так на закрытие тега поля можно сохранять значение поля в буфферный словарик под соответствующим ключем, а на закрытие тега записи сохранять накопившийся словарик в CSV-файл в потоковом режиме дописывая в него строчку.
Так и террабайтные xml можно без мороки обрабатывать, лишь бы одна максимальная его запись в память помещалась. Думаю на гитхабе готовых SAX XML to CSV конвертеров валом. Ну или стоит сделать, если нет (хотя я сильно удивлюсь). Думаю код поместится на полтора экрана со всеми обработками ошибок и CLI.
0
Ну, ради объективности, это ФИАС такой простой, что у него одна запись. У меня были случаи, когда нужно было парсить 8 гигабайт, при этом данные размазаны по иерархии XML. Так что я вынужден был держать верхние уровни в памяти тоже, да и конкретно SAX при этом большого удовольствия не доставляет.
P.S. Отдельный вопрос — почему бы не прочитать ФИАС в формате .dbf, где такой проблемы вообще не существует как класса.
P.S. Отдельный вопрос — почему бы не прочитать ФИАС в формате .dbf, где такой проблемы вообще не существует как класса.
0
На счёт дбф я даже не стал упоминать ввиду очевидности. А где 8 гигов, там и 28. Никакой памяти не напасешься, так что конвертить тем же саксом во что-то удобоваримое типа набора быстрых key-value коллекций на диске или реляционной бд или той же монги и работать уже с этим. Да, метод "сакс", но как иначе построить масштабируемое решение?
0
Очевидно что принципиально больше никак. И против решения ничего не имею, это было лишь небольшое уточнение. Впрочем, как вариант могу предложить что-то вроде этого:
jawher.wordpress.com/2011/02/28/introducing-immanix-java-library-process-xml-using-parser-combinators
Я пользовался, в том числе для разбора 8 гиговых xml. По сравнению с голым SAX — чуть удобнее, примерно при тех же ресурсах.
А упоминание про .dbf… ну не знаю, я как-то запросил у смежной команды периодически импортировать к нам OpenStreetMap. При этом явно написал — берите pbf. Потому что содержимое идентично, а размеры в разы меньше. И что бы вы думали — в итоге реализовали импорт из xml. Считайте, что это была агитация за то, чтобы рассмотреть все варианты :)
jawher.wordpress.com/2011/02/28/introducing-immanix-java-library-process-xml-using-parser-combinators
Я пользовался, в том числе для разбора 8 гиговых xml. По сравнению с голым SAX — чуть удобнее, примерно при тех же ресурсах.
А упоминание про .dbf… ну не знаю, я как-то запросил у смежной команды периодически импортировать к нам OpenStreetMap. При этом явно написал — берите pbf. Потому что содержимое идентично, а размеры в разы меньше. И что бы вы думали — в итоге реализовали импорт из xml. Считайте, что это была агитация за то, чтобы рассмотреть все варианты :)
0
Аналогично, парсил ФИАС используя простую конструкцию
using (var xmlReader = new XmlTextReader(file))
{
while (xmlReader.Read())
{
if (xmlReader.Name != "Object")
continue;
var address = XElement.Load(xmlReader.ReadSubtree());
...
}
}
Почти не требует памяти (Мне хватало 128мб, с учетом того что в памяти хранились все нужные объекты, но я только до городов сверху вниз парсил), работает довольно шустро.0
UFO just landed and posted this here
Ага…
героически игнорируем гениальный по экономичности подход SAX парсеров
сохраняем руками в четыре файла (open, seek, read/write уж на крайний случай)
используем замечательный инструмент (спасибо за явную конверсию типов, раньше не обращал внимание),
но для чего? Переименовать столбцы и сохранить в итоговый файл?
героически игнорируем гениальный по экономичности подход SAX парсеров
сохраняем руками в четыре файла (open, seek, read/write уж на крайний случай)
используем замечательный инструмент (спасибо за явную конверсию типов, раньше не обращал внимание),
но для чего? Переименовать столбцы и сохранить в итоговый файл?
+1
Изложите ваш подход? Опыт бесценен.
-1
habr.com/ru/post/171447
уже есть вполне готовый пример. Или интересует именно ФИАС, питоном и пачкой зараз?
Но смысл? В чем сверхзадача?
Получить данные — это один промежуточный процесс, потом с ними надо что-то сделать полезное.
уже есть вполне готовый пример. Или интересует именно ФИАС, питоном и пачкой зараз?
Но смысл? В чем сверхзадача?
Получить данные — это один промежуточный процесс, потом с ними надо что-то сделать полезное.
0
Сверхзадача — выяснить как чувствует себя pandas при малых объемах памяти и большим датасетом, если ли предел модуля. Какова скорость работы на сверхбольших данных.
Странно, что все смотрят только в сторону конвертации xml-csv.
Странно, что все смотрят только в сторону конвертации xml-csv.
0
Учитывая, что внутри прячется numpy, то ответ довольно предсказуемый.
Немного лучше, чем нативный код на питоне.
www.draketo.de/english/python-memory-numpy-list-array
В любом случае Pandas пока что хранит данные в оперативной памяти, так что всё плохо и будет потихоньку выпадать в своп при превышении
Немного лучше, чем нативный код на питоне.
www.draketo.de/english/python-memory-numpy-list-array
В любом случае Pandas пока что хранит данные в оперативной памяти, так что всё плохо и будет потихоньку выпадать в своп при превышении
0
UFO just landed and posted this here
Делал похожую задачу, тоже связанную с ФНС (данные о среднесписочном составе — представляют собой огромное кол-во XML — файлов. Требовалось привести их к виду, привычному для юристов — электронной таблице Excel, т.е. много мелких XML файлов объединить в одну или несколько таблиц Excel) с помощью XSLT -преобразования. Реализовал с помощью программы xsltproc пакета libxslt (в archlinux, в других дистрах может по другому). Самым сложным было сочинить XSL-фильтр, через который прогонялся XML-файл, т.к. довольно редко приходится работать с данными в XML, но хотелось сделать красиво.
-1
Много мелких файлов и один большой файл — это две совершенно непохожие задачи. Особенно в свете xslt, которому нужна вся модель документа в памяти.
0
Наверное, всё-таки похожие, поскольку я не думаю что XSLT-фильтр сначала целиком прочитывает весь файл в память, а потом разбирает его. Я склонен к тому что он делает это порциями, по мере чтения файла. Но на 100% пока не уверен, т.к. сам лично не проверял.
-1
Специальная утилита для склеивания CSV-файлов. Серьёзно?
0
Если вы это в сети нашли:
copy *.csv big.csv
, то там названия столбцов не задаются при склейке.0
Вы можете сделать первый файл с названиями столбцов
copy header.csv + 1.csv + 2.csv +… big.csv
copy header.csv + 1.csv + 2.csv +… big.csv
0
Это вы про a,b,c т.д.? Да, это большая потеря.
А имя файла в tree = ET.parse("add-30-40.xml",parser=parser) вы вручную каждый раз подставляли? Нельзя было просто циклом пройтись сразу по всем XML-файлам и записать разом в один CSV файл?
Кстати, заголовок в CSV вообще не обязателен (в т.ч. для pandas).
0
Нельзя было просто циклом пройтись сразу по всем XML-файлам и записать разом в один CSV файл?
С адресным реестром (база из статьи) это возможно. А вот с «домами» — база из архива на 29 Гб уже нет, так как база битая — некоторые теги не закрыты, поэтому парсер вылетает.
*Из 119 чанок по 220 Мб, только половина парсится без проблем.
Кроме того, не ясна структура, а большой файл после создания не открыть для уточнения.
Кстати, заголовок в CSV вообще не обязателен (в т.ч. для pandas).
Все верно. Эти названия необходимы для ориентации в датасете.
0
Sign up to leave a comment.
Как обработать большие датасеты в pandas. Работаем с базой ФИАС, используя python и 8Гб памяти