Пример того, как я пришел к простым правилам обработки спарсенных таблиц. Техника определяет тактику (мое теннисное убеждение), и правила также нельяз написать без учета инструментов, которые используются для обработки.
Я недавно "запал" на Pandas. И только вчера подобрал и попробовал методы для чистки таблиц. Т.е., я еще не освоил "технику" настолько, чтобы не думать о ней, но сосредоточиться на последовательности процессаов и "тактике" перебора файлов...
Наверное, поэтому мне так трудно. Очевидно, что я совершаю методическую ошибку. Я пытаюсь одновременно "ехать на автомобиле и ремонтировать его" (еще одна метафора... только для того, чтобы оправдать собственную глупость.
Здесь я попытался было проверить все чистящие операторы в одном методе в цикле, но влетел в непонятные ошибки, подключил дебаггер... оказалось, что один из файлов (апрель) в папке с заголовком, а остальные - нет... Начал пробовать все подряд, а потом написал-таки правила...
Итак, сначала о файлах таблиц... почему я влетел в ошибки? Прежде, чем окунуться в их вылавливание, попробуем найти перовпричину.
Я хотел все запихнуть в один цикл по файлам, но эти файлы не "однотипные", хотя и однородные (красиво говорю, однако). Я их скачал "давно" и "забыл", что они из себя представляют.
Правильнее всего, наверное было бы обработать их тогда же, когда и скачал. Но это не всегда возможно, кроме того, файлы бывают и длинными. Так что, склеивать все сразу в один большой файл... - это не есть првильно всегда...
А что правильно всегда? Нужны правила для папок и вообще... правила для обработки.
Step-by-step debugging with IPython
Stepping into a function in IPython ipdb.runcall(foo, 1, 2)
26.2. pdb — The Python Debugger
Правила папок¶
- Однородные файлы должны быть однотипными (чтобы их можно было обрабатывать в цикле)
- Следствие 1 из 1: Все эксперименты и настройки в отдельных временных папках для временных файлаов.
- Следствие 2 из 1: Результаты обработки в новую папку с большим номером версии.
- Следствие 3 из 1: Во всех файлах папки обязательна метка в имени файла (для фильтра).
- Следствие 4 из 1: В некоторых папках можно размещать файлы-комментарии с одинаковыми именами. Например info.txt
- Следствие 1 из 5: info.txt нужно создавать автоматически, с якорями (тегами?) для парсинга файлйа, например "date:" (альтернатива - .json)?
Правила просмотра¶
- Шаблон визуального контроля - это .ipynb шаблон в ячейках которого код для циклов по файлам папки.
- Визуальный контроль. Считываем по очереди в объект Pandas и печатаем каждый объект - возможен отдельный файл .ipynb. Можно просто в цикле распечатать фрагменты из разнфх мест для каждого файла.
- Планирование дальнейших действий. Потом спланировать действия (и их последовтельность) для алгоритма обработки (открытия, перебора, очистки, склеивания)... например, в данном случае выгодно сначала склеить, а потом чистить. Для этого должны быть ячейки - шаблоны со списками возможных действий... Может быть, сразу фрагменты кода использовать? В каждой ячейке свой метод (он уже проверен, потому в перспективе можно их в цикл заряжать... Единственное неудобство - отступы (попробовать TAB Shift+TAB) в Notebook
- Логирование (запись плана и произведенных действий) Подчеркиваю, что надо отразить последовательности действий (вызова методов), записи об исправлениях в файлах (можно %load, %write)..., например, если убрать строку-заголовок в первом файле все записи можно обрабатыват в цикле. Запись об этом событии должна быть в тдельной ячейке..., а все дальнейшие плановые события должны быть скопированы и перенесены в файл .ipynb в котором будет записан процесс дальнейшей обработки.
- Удаление лишних файлов. Пока не знаю, как это лучше делать... но мусор собирать надо..., поэтому пока надо бы готовить полные пути "старых файлов" для сборщиков мусора. Или просто переимановывать папки, например, добавлять в конец "_bak"
####Правила работы со столбцами
- Проверяем все первоисточники на предмет соответствия едминому шаблону например, COLNAMES =['Brandt', '2014y', '2013y', '1413y', '2014m', '2013m', '1413m', 'Datem']
- Для всех объектов DataFrame одна строка заголовков вставляется при считывании csv
- Для всех объектов DataFrame определяются NaN для считывании csv
Правила сохранения результатов¶
Этот фрагмент я пишу после того, как закончил селдующий пост. Там я сцепил вместе и почистил 9 файлов (а нужно 12), получил очередной промежуточный результат. Его, естественно, надо сохранить.
- Каждый этап преобразований в отдельную папку (чтобы потом можно было удалить всю папку)
- При этом "старые" файлы во вложенных папках (старые - это первоисточники и обработка).
- Оставлять ли первоисточники?
- Обработку удалять после того, как оттестирован сводный файл?
- Таблицы-исходники это, то (csv), что вышло из парсера. В этом примере я просто удалил строку заголовка в файле апреля, она создавала большие проблемы, например при вставке столбца строк (object) вида '21-12-2014' оказалось, что в первой строке строка '1413m%', а я потом собирался все это конвертировать в Date64.
- Такие ошибки выявляются при визуальном контроле структуры. Как, оставаясь в Notebook, редактировать строки?
- !ls '', !tree
- !mkdip '' - создать папку для новой версии
- %load ''
- %%writefile tofilepath """ """
Далее эксперименты, в процессе которых все эти умные мысли посетили мою голову¶
import sys
sys.path
import pdb
dir(pdb)
import os
import pandas as pd
#import matplotlib.pyplot as plt
#import numpy as np
# Path to dir with files
DIRPATH = '/media/MYLINUXLIVE/Documents/Xpdf/aerbu_2014_all_csv/1aug2/'
# Insert my columns names in Dataframe objects
COLNAMES =['Brandt', '2014y', '2013y', '1413y', '2014m', '2013m', '1413m', 'Datem']
months = ['january', 'febrary', 'march', 'april', 'may', 'jun',
'july', 'august','september', 'october','november', 'december']
dict = {'january':'31-1', 'febrary':'28-2', 'march':'31-1',
'april':'30-4', 'may':'31-5', 'jun':'30-6',
'july':'31-7', 'august':'31-8','september':'30-9',
'october':'31-10','november':'30-11', 'december':'31-12'}
pdall = pd.DataFrame()
Вот этот код начал выдавать ошибки, в следующем посте я все исправил, результат работы - там, а здесь лишь классический пример ошибочного ламерского подхода. 1) Надо представлять структуру данных 2) Надо иметь четкий план - в данном случае очень важна последовательность чистки...
Например, есть в элементы "-" (во всех столбцах) и "-45.3%" (в дух столбцах), я забабахал str.replace('%','').astype(float) и получил ошибку на элементах "-", о существовании которых "не знал", потому что не удосужился просмотреть исходные файлы ... Надо бы упростить эту процедуру... Вот, пока нашел вариант с PDB
import pdb; pdb.set_trace()
for csvfile in os.listdir(DIRPATH):
if csvfile.startswith('eng_car-sales-in'):
csvfile_path = os.path.join(DIRPATH, csvfile)
pdtemp = pd.read_csv(csvfile_path, error_bad_lines=False, names=COLNAMES)
# Replace '*', '%' and convert object to Int
pdtemp['Brandt'] = pdtemp['Brandt'].str.replace('*','')
pdtemp['1413y'] = pdtemp['1413y'].str.replace('%','').astype(float)
pdtemp['1413m'] = pdtemp['1413m'].str.replace('%','').astype(float)
# Parse month name from filename
namem = csvfile.split('-')[3] # 'april' for example
# Replace strings with dict 'april':'30-4',
pdtemp['Datem'] = dict[namen] + '-2014' # '30-4-2014'
#Concat month dataframes to pdall
pdall = pd.concat(pdall, pdtemp, ignore_index=True)
Вот пример пошагового распечатывания файлов с помошью дебаггера ...надо просто задать точку останова¶
Если файлы длинные, то надо бы их рассмтривать по-одному..., но как это делать? Пока не догадался. Не будем решать задачи, которых пока нет (длинных файлов)... Здесь лучше отметим, что в выходной поток дебаггера можно ведь и строки (с комментариями записывать... А чтобы сократить количество строк можно на печатьвыводить фрагменты...
import pdb; pdb.set_trace()
for csvfile in os.listdir(DIRPATH):
if csvfile.startswith('eng_car-sales-in'):
csvfile_path = os.path.join(DIRPATH, csvfile)
pdtemp = pd.read_csv(csvfile_path, error_bad_lines=False, names=COLNAMES)
print (csvfile, pdtemp)
Но сбой произошел... и весь дебаггера исчез... Это можно использовать... Например, на задавать печать в коде, а печатать в объект в дебаггере... Здесь надо бы научиться вызывать предыдущие команды... В Notebook я их пока не нашел, а надо бы...
Наверное, надо попробовать копипастить фрагмены вывода дебаггера в другие ячейки... Это трудоемкое занятие, но только в первый раз, потом можно копипастить уже ячейки из предыдущих файлов Notebook. Сразу же надо искать компактный формат записи в такие яейки...
pdtemp
pdtemp = pd.read_csv(csvfile_path, error_bad_lines=False, names=COLNAMES, skiprows=0)
pdtemp.head()
Вот у нас есть один заголовок таьлицы, мы его поменяем на другой. Однако, старый заголовок (строка) остается, если мы его не пропустим при считывании:
pdtemp = pd.read_csv(csvfile_path, error_bad_lines=False, names=COLNAMES, skiprows=1)
pdtemp.head()
pdtemp.head()['Brandt']
for csvfile in os.listdir(DIRPATH):
if csvfile.startswith('eng_car-sales-in'):
csvfile_path = os.path.join(DIRPATH, csvfile)
pdtemp = pd.read_csv(csvfile_path, error_bad_lines=False, names=COLNAMES, skiprows=0)
print (pdtemp.head())
pdtemp[:3]
Посты чуть ниже также могут вас заинтересовать
Комментариев нет:
Отправить комментарий