Найти - Пользователи
Полная версия: алгоритм обработки .txt файла
Начало » Python для новичков » алгоритм обработки .txt файла
1
xenon
Здравствуйте, уважаемые форумчане!
Мне необходимо перевести данные из текстовых файлов блокнота в более структурированный вид для дальнейшей обработки в екселе. Файлы большие (по 1 мб), но имеют определенную структуру, хотя и путанную (см. вложение).
Конечно у меня появилось желание это автоматизировать … (иначе придется в ручную …)
Хотелось бы услышать советы бывалых: как лучше подступиться, какие грабли обойти, какими модулями воспользоваться и т.д.
У меня очень мелкий опыт работы в питоне, я хотел бы его расширить на примере решения данной задач.
Пока вижу след. алгоритм:
1. считываем весь файл в переменную
2. перебирать по строкам и сравнивать с условием (начало строки удовлетворяет условию)
3. в случае удовлетворения разбивать по разделителям
4. формировать гигантский список (исходя из кучи условий)
5. запись в файл

Очень смущает работа с условиями (if … elif …) - у меня они получаются просто огромными,а в итоге все равно что-нить да пропустишь …
FishHook
Во-первых, файл можно (и нужно) читать (как собственно и писать) порциями-строками, не загружая в память все содержимое файла и не создавая “гигантского списка”. Во-вторых, интересен размер оперативной памяти Вашей машины, для которой 1Мб - это гигантский список. В-третьих, огромные конструкции if, как правило означают плохо продуманный алгоритм. Наверняка можно создать словарь “значение : функция”.
py.user.next
xenon
3. в случае удовлетворения разбивать по разделителям
там у тебя не разделители, а фиксированные поля
по заголовку с номерами определяется ширина каждого поля (сохраняется список)
для каждой строки под заголовком с номерами перебираются ширины полей
срез строки подойдёт
xenon
В-третьих, огромные конструкции if, как правило означают плохо продуманный алгоритм. Наверняка можно создать словарь “значение : функция”
- понял, буду использовать словари

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

а “неправильные” строки типа “подрост …”, “единичные деревья …” и т.д. - необходимо отфильтровывать как раз с использованием словарей?
doza_and
Я посмотрел файл.
Экселовский файл надо делать наверное с большим количеством страниц, По странице на лесничество :(
Насколько я понимаю заголовки таблиц надо выбросить. Для этого подойдут регулярные выражения (по опыту этот подход более устойчив к изменениям формата файла) или просто пересчитывая строки.
Остальное лучше разбирать тоже регулярными выражениями а не разделителями поскольку там встречаются “БОНИТЕТ ПО ТУМ” которые как я понял одно значения.

Вообще для такого файла эксел плохой формат. У вас явно выраженная двухуровневая древовидная структура. В данных куча пробелов. Лучше hdf5 или на худой конец yaml.
py.user.next
xenon
начинаю понимать, большое спасибо за идею
для начала разберись в самом формате файла

вот, к примеру
: 1 :  2  :         3       :4: 5 :  6 : 7 : 8 : 9:10:11:12:  13  : 14 : 15 :  16 : 17  :18: 19 : 20 : 21 : 22  : 23 :     24      :
------------------------------------------------------------------------------------------------------------------------------------

...

15 57,1 10Б 1 25 Б 120 25 24 12 4 3 ЗМ 0,6 19 1085 1085 2
7Е3П 2 17 Е 90 17 16 0,4 10 571 400 1
П 17 16 171 1
подрост: 5П3Е2К (20) 3,0 м, 3,0 тыс.шт/га,БЛАГОНАДЕЖНЫЙ
ОЗУ: полосы леса по берегам рек заселенных бобрами

19 11,4 10Б 1 25 Б 120 25 24 12 4 3 ЗМ 0,5 16 182 182 2
7Е3П 2 17 Е 90 17 16 0,3 7 80 56 1
П 17 16 24 1
что этот кусок означает ?
xenon
Большое спасибо всем откликнувишмся!!!

Экселовский файл надо делать наверное с большим количеством страниц, По странице на лесничество :(
- нет, в екселевском файле одна страница, там идентификация идет по номеру квартала (над заголовком) + номер участка выдела (колонка №1)

“БОНИТЕТ ПО ТУМ” которые как я понял одно значения.
- да, вы правы

Вообще для такого файла эксел плохой формат. У вас явно выраженная двухуровневая древовидная структура. В данных куча пробелов. Лучше hdf5 или на худой конец yaml.
- спасибо за информацию к размышлению.

что этот кусок означает ?
первые три строки (после многоточия):
есть участок под номером 15 (колонка №1), его площадь 57.1 га (колонка №2), далее с 3 по 18 колонку идет описание леса для 2-ух ярусов (ярус 1 и ярус 2 - колонка №4) по породам - для всего участка №15
четвертая строка - общее описание (подроста, и т.д.) для всего участка №15
пятая строка - общее описание (ОЗУ и т.д.) для всего участка №15
далее пустая строка (разделитель)
новый участок №16 …

постановка задачи:
первые три строки участка №15 переносятся в таком же порядке в екселе, 4 и 5 строка должна оказаться в новой колонке напротив 15 участка (т.е. создать новые колонки для ОЗУ, подроста и т.д. и занести в них данные), если есть еще “общие” строчки, то они переносятся в новую колонку.

думаю с начало попробовать так:
по заголовку с номерами определяется ширина каждого поля (сохраняется список)
для каждой строки под заголовком с номерами перебираются ширины полей
срез строки подойдёт

+ использовать словари, т.к. в документе используется определенный строгий набор терминов: “подрост:”, “ОЗУ:”, “БОНИТЕТ …” - их вполне можно перечислить в словаре и отлавливать при помощи срезов и условий.

Изначально надо было выложить файл-пример конечного результата - с тормозил, простите.
py.user.next
xenon
думаю с начало попробовать так:
подготовка:
1. привести таблицу к стандартному виду (нормализовать)
1.1. удалить заголовки
1.2. разделить на страницы

реализация:
1. написать обработчик программы
1.1. создать структуру данных
1.2. передать таблицу обработчику таблицы
1.3. добавить данные таблицы в структуру данных
1.4. сохранить структуру данных в файл

2. написать обработчик таблицы
2.1. разделить таблицу на страницы
2.2. передать каждую страницу обработчику страницы
2.3. добавить данные страниц в структуру данных

3. написать обработчик страницы
3.1. разделить страницу на участки
3.2. передать каждый участок обработчику участка
3.3. добавить данные участков в структуру данных

4. написать обработчик участка
4.1. разделить участок на площадь, ярусы и комментарии
4.2. передать каждый ярус обработчику яруса
4.3. добавить данные площади, ярусов и комментариев в структуру данных

5. написать обработчик яруса
5.1. разделить ярус на составляющие


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

add
чуть поправил там окончания
xenon
py.user.next - спасибо большое, буду пробовать!!!
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB