Как классифицировать / классифицировать строки в соответствии с правилами регулярных выражений в Python - PullRequest
6 голосов
/ 08 марта 2012

Я пишу сценарий ETL на Python, который получает данные в файлах CSV, проверяет и очищает данные, а также классифицирует или классифицирует каждую строку в соответствии с некоторыми правилами и, наконец, загружает ее в базу данных postgresql.

Данные выглядят так (упрощенно):

ColA, ColB, Timestamp, Timestamp, Journaltext, AmountA, AmountB

Каждая строка является финансовой транзакцией. То, что я хочу сделать, это классифицировать или классифицировать транзакции на основе некоторых правил. Правила в основном представляют собой регулярные выражения, соответствующие тексту в столбце Journaltext.

Так что я хочу сделать что-то вроде этого:

transactions = []
for row in rows:
    t = Transaction(category=classify(row.journaltext))
    transactions.append(t)

Я не уверен, как эффективно написать функцию classify ().

Вот как работают правила классификации:

  • Существует ряд категорий (другие могут быть добавлены позже)
  • Каждая категория имеет набор подстрок или регулярных выражений, которые, если Journaltext транзакции соответствует этому выражению или содержит эту подстроку, то эта транзакция принадлежит этой категории.
  • Транзакция может быть только в одной категории
  • Если категория FOO имеет подстроки 'foo' и 'Foo', а другая категория BAR имеет подстроки 'football', то транзакция с Journaltext = 'food' должна быть помещена в категорию FOO, поскольку она соответствует только FOO , но транзакция с Journaltext = 'footballs' должна быть помещена в категорию BAR. Я думаю, это означает, что я должен поставить приоритет или подобный для каждой категории.
  • Если транзакция не соответствует ни одному из выражений, она либо не указана в категории, либо будет помещена в категорию заполнителя с именем «НЕИЗВЕСТНО» или аналогична. Это не имеет большого значения.

Ok. Итак, как мне представить эти категории и соответствующие правила в Python?

Буду очень признателен за ваш вклад. Даже если вы не можете предоставить полное решение. Просто все, что намекнет мне в правильном направлении, будет здорово. Спасибо.

Ответы [ 2 ]

2 голосов
/ 08 марта 2012

как насчет этого решения в псевдо-питоне:

def classify(journaltext):
    prio_list = ["FOO", "BAR", "UPS", ...] # "..." is a placeholder: you have to give the full list here.
    # dictionary: 
    # - key is the name of the category, must match the name in the above prio_list
    # - value is the regex that identifies the category
    matchers = {"FOO": "the regex for FOO", "BAR": "the regex for BAR", "UPS":"...", ...}
    for category in prio_list:
        if re.match(matchers[category], journaltext):
            return category
    return "UNKOWN" # or you can "return None"

Особенности:

  • здесь есть prio_list, который представляет все категории в порядке убывания.
  • он пытается соответствовать в порядке списка.
  • Соответствует регулярному выражению из словаря matchers .Таким образом, имена категорий могут быть произвольными.
  • функция возвращает имя категории
  • , если ничего не найдено, тогда вы получаете название категории заполнителя.

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

2 голосов
/ 08 марта 2012

Без какого-либо дополнительного пуха:

categories = [
  ('cat1', ['foo']),
  ('cat2', ['football']),
  ('cat3', ['abc', 'aba', 'bca'])
]

def classify(text):
  for category, matches in categories:
    if any(match in text for match in matches):
      return category
  return None

В Python вы можете использовать оператор in для проверки подмножеств строки. Вы можете добавить некоторые вещи, такие как isinstance(match, str), чтобы проверить, используете ли вы простую строку или объект регулярных выражений. Насколько он продвинут, зависит от вас.

...