2016-07-28 23 views
2

У меня есть столбец данных данных Pandas, содержащий текст, который нужно очистить от строк, соответствующих различным шаблонам регулярных выражений. Моя текущая попытка (приведенная ниже) проходит через каждый шаблон, создавая новый столбец, содержащий совпадение, если он найден, а затем петли через фреймворк данных, разделяя столбец в найденном совпадении. Затем я удаляю ненужный соответствующий столбец «re_match».Удаление строк, совпадающих с несколькими шаблонами регулярных выражений из серии pandas

Хотя это работает для моего нынешнего варианта использования, я не могу не думать, что в пандах должен быть гораздо более эффективный, векторный способ сделать это без необходимости использовать iterrows() и создать новый столбец. Мой вопрос в том, есть ли более оптимальный способ удаления строк, которые соответствуют нескольким шаблонам регулярных выражений из столбца?

В моем текущем случае использования нежелательные строки всегда находятся в конце текстового блока, следовательно, использование split(...)[0]. Однако было бы замечательно, если бы ненужные строки могли быть извлечены из любой точки текста.

Также обратите внимание, что объединение регулярных выражений в один длинный одиночный шаблон будет непревзойденным, так как десятки паттернов будут меняться на регулярной основе.

df = pd.read_csv('data.csv', index_col=0) 
patterns = [ 
    '(regex1 \d+)', 
    '((?: regex 2)? \d{1,2})', 
    '(\d{0,2}.?\d{0,2}-?\d{1,2}.?\d{0,2}regex3)', 
] 

for p in patterns: 

    df['re_match'] = df['text'].str.extract(
     pat=p, flags=re.IGNORECASE, expand=False 
    ) 
    df['re_match'] = df['re_match'].fillna('xxxxxxxxxxxxxxx') 

    for index, row in df.iterrows(): 
     df.loc[index, 'text'] = row['text'].split(row['re_match'])[0] 

df = df.drop('re_match', axis=1) 

Спасибо за вашу помощь

+0

Я не знаком с 'pandas', но проблема здесь, как я понял, может исходить от структуры данных, называемой' dataframe'. Простым способом преодоления этой задачи может быть просто использование чистого python или sed. – fronthem

ответ

0

Существует действительно и это называется df.applymap(some_function).
Рассмотрим следующий пример:

from pandas import DataFrame 
import pandas as pd, re 
df = DataFrame({'key1': ['1000', '2000'], 'key2': ['3000', 'digits(1234)']}) 

def cleanitup(val): 
    """ Multiplies digit values """ 
    rx = re.compile(r'^\d+$') 
    if rx.match(val): 
     return int(val) * 10 
    else: 
     return val 

# here is where the magic starts 
df.applymap(cleanitup) 

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