2016-07-28 13 views
2

Ich habe eine Pandas Dataframe Spalte mit Text, der von Strings gereinigt werden muss, die verschiedene Regex-Muster entsprechen. Mein aktueller Versuch (siehe unten) durchläuft jedes Muster, erstellt eine neue Spalte mit der gefundenen Übereinstimmung und durchläuft dann den Datenrahmen, wobei die Spalte bei der gefundenen Übereinstimmung geteilt wird. Ich lösche dann die nicht benötigte passende Spalte 're_match'.Entfernen von Strings, die mehrere Regex-Muster aus Pandas Serie

Während dies für meinen aktuellen Anwendungsfall funktioniert, kann ich nicht anders, als zu denken, dass es eine viel effizientere, vektorisierte Methode in Pandas geben muss, ohne iterrows() zu verwenden und eine neue Spalte zu erstellen. Meine Frage ist, gibt es eine optimale Möglichkeit zum Entfernen von Zeichenfolgen, die mehrere Regex-Muster aus einer Spalte entsprechen?

In meinem aktuellen Anwendungsfall sind die unerwünschten Zeichenfolgen immer am Ende des Textblocks, daher die Verwendung von split(...)[0]. Es wäre jedoch großartig, wenn die unerwünschten Zeichenfolgen von irgendeinem Punkt im Text extrahiert werden könnten.

Beachten Sie auch, dass die Kombination der Regexes zu einem einzigen langen Muster nicht vorzuziehen ist, da sich Dutzende von Mustern regelmäßig ändern.

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) 

Vielen Dank für Ihre Hilfe

+0

Ich bin nicht vertraut mit Pandas, aber das Problem hier, wie ich verstanden habe, könnte aus der Datenstruktur namens "Dataframe" stammen. Der einfache Weg, um diese Aufgabe zu lösen, könnte nur eine reine Python oder Sed sein. – fronthem

Antwort

0

Es ist in der Tat, und es wird df.applymap(some_function) genannt.
Betrachten Sie das folgende Beispiel:

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) 

Offensichtlich ich es wieder gut gemacht, aber jetzt in jeder Zelle mit nur Stellen vor, werden diese mit 10 multipliziert worden ist, hat jeder anderer Wert unberührt gelassen.
In diesem Sinne können Sie Ihre Werte bei Bedarf in der Funktion cleanitup() überprüfen und neu anordnen.