Подход на основе панд / регулярных выражений для сопоставления первой строки из списка строк - PullRequest
1 голос
/ 10 апреля 2020

Извинения, если это перекрестный список; Я искал некоторое время!

Я работаю с очень большими, очень грязными данными в Pandas. Интересующая переменная представляет собой строку и содержит один или несколько экземпляров бизнес-имен с (без) типичными бизнес-суффиксами (например, LL C, LP, LTD). Например, у меня может быть «AB C LL C XYZ, LL C XYZ, LTD». Моя цель - найти первый экземпляр суффикса, соответствующего списку. Мне также нужно извлечь все до первого матча. Для приведенного выше примера я бы нашел / извлек "AB C LL C". Рассмотрим следующие данные:

 sfx = ['LLC','LP','LTD']
 dat = pd.DataFrame({'name':['ABC LLC XYZ,LLC XYZ, LTD','IJK LP, ADDRESS']})

Пока что я выполнил это для одного случая запутанным способом, который мне не подходит:

one_string = 'ABC LLC XYZ,LLC XYZ, LTD'
indexes=[]
keywords=dict()
for sf in sfx:
    indexes.append(one_string.index(sf,0))
    keywords[one_string.index(sf,0)]=sf
    indexes.sort()
    print(one_string[0:indexes[0]]+ keywords[indexes[0]])

Я ищем более эффективный (возможно, векторизованный) способ сделать это для всего столбца. Кроме того, мне нужно включить регулярное выражение, чтобы избежать извлечения суффиксов, когда такие же буквенные комбинации появляются в тексте. Шаблон регулярного выражения, который мне нужен, может выглядеть примерно так (LL C появляется после пробела или запятой и находится в конце слова):

reg_pattern = r`(?<=[\s\,])LLC\b|(?<=[\s\,])LP\b|(?<=[\s\,])LTD\b`

ОБНОВЛЕНИЕ

Простое решение от Wiktor. Я также понял, что как только у меня будет извлечено то, что предшествует суффиксу, мне нужно будет извлекать все, что идет после него, отдельно. Бросить решение в позитивный взгляд не сработало. Очень признателен!

1 Ответ

1 голос
/ 11 апреля 2020

Чтобы получить тексты, которые предшествовали, включая ключевые слова, вы можете использовать

pattern = r"^(.*?\b(?:{}))(?!\w)".format("|".join(map(re.escape, names)))

, а затем

df['results'] = df['texts'].str.extract(pat, expand=False)

Откорректировать имена столбцов в соответствии с вашим кодом. Шаблон будет выглядеть как ^(.*?\b(?:LLC|LP|LTD))(?!\w) и будет означать:

  • ^ - начало строки
  • (.*?\b(?:LLC|LP|LTD)) - группа 1 (это значение будет возвращено .str.extract ):
    • .*? - любые 0+ символов, кроме символов разрыва строки, как можно меньше
    • \b - граница слова
    • (?:LLC|LP|LTD) - один из альтернатив: LLC, LP или LTD
  • (?!\w) - не сопровождается словом char: letter, di git или _.

Чтобы получить весь текст после совпадения, вы можете использовать

pattern = r"\b(?:{})(?!\w)(.*)".format("|".join(map(re.escape, names)))

Здесь шаблон будет выглядеть как \b(?:LLC|LP|LTD))(?!\w)(.*) и сначала будет соответствовать одному из имен как целому слову. и затем захватывает в Группу 1 всю оставшуюся часть строки (соответствует (.*) - любые 0 или более символов, кроме символов разрыва строки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...