2016-07-28 21 views
9

Ich habe eine große Datendatei und ich muss Zeilen löschen, die in bestimmten Buchstaben enden. HierPython: Wie lösche Zeilen mit bestimmten Zeichen?

ist ein Beispiel für die Datei Ich verwende:

User Name  DN 
MB212DA  CN=MB212DA,CN=Users,DC=prod,DC=trovp,DC=net 
MB423DA  CN=MB423DA,OU=Generic Mailbox,DC=prod,DC=trovp,DC=net 
MB424PL  CN=MB424PL,CN=Users,DC=prod,DC=trovp,DC=net 
MBDA423  CN=MBDA423,OU=DNA,DC=prod,DC=trovp,DC=net 
MB2ADA4  CN=MB2ADA4,OU=DNA,DC=prod,DC=trovp,DC=netenter code here 

-Code Ich bin mit:

from pandas import DataFrame, read_csv 
import pandas as pd 
f = pd.read_csv('test1.csv', sep=',',encoding='latin1') 
df = f.loc[~(~pd.isnull(f['User Name']) & f['UserName'].str.contains("DA|PL",))] 

Wie kann ich Syntax für reguläre Ausdrücke verwenden, um die Worte zu löschen, die "enden in DA "und" PL "aber stellen Sie sicher, dass ich die anderen Zeilen nicht lösche, weil sie" DA "oder" PL "in ihnen enthalten?

Es sollte die Zeilen löschen und ich mit einer Datei am Ende wie folgt:

User Name  DN 
MBDA423  CN=MBDA423,OU=DNA,DC=prod,DC=trovp,DC=net 
MB2ADA4  CN=MB2ADA4,OU=DNA,DC=prod,DC=trovp,DC=net 

Die ersten 3 Zeilen werden gestrichen, weil sie in DA und PL beendet.

Antwort

7

Sie diesen Ausdruck verwenden könnte

df = df[~df['User Name'].str.contains('(?:DA|PL)$')] 

Es werden alle Zeilen zurückgegeben, die nicht in DA oder PL enden.

Die ?: ist so, dass die Klammern nichts erfassen würden. Andernfalls würden Sie sehen Pandas die folgende (harmlos) Warnung Rückkehr:

UserWarning: This pattern has match groups. To actually get the groups, use str.extract. 

Alternativ mit endswith() und ohne reguläre Ausdrücke, könnte die gleiche Filterung unter Verwendung der folgenden Gleichung erreicht werden:

df = df[~df['User Name'].str.endswith(('DA', 'PL'))] 

Wie erwartet, wird die Version ohne regulären Ausdruck schneller sein. Ein einfacher Test, bestehend aus big_df, die von 10.001 Kopien Ihrer ursprünglichen df besteht:

# Create a larger DF to get better timing results 
big_df = df.copy() 

for i in range(10000): 
    big_df = big_df.append(df) 

print(big_df.shape) 

>> (50005, 2) 

# Without regular expressions 
%%timeit 
big_df[~big_df['User Name'].str.endswith(('DA', 'PL'))] 

>> 10 loops, best of 3: 22.3 ms per loop 

# With regular expressions 
%%timeit 
big_df[~big_df['User Name'].str.contains('(?:DA|PL)$')] 

>> 10 loops, best of 3: 61.8 ms per loop 
+0

Hat eine Regex nicht endswith zu akzeptieren? Ich vermute, es benutzt einen unter der Haube. –

+0

Ich dachte auch, sogar die Docs behaupten, dass das erste Argument ein Muster ist, aber ich konnte es nicht dazu bringen, eine Regex zu erkennen. –

+1

@AndyHayden anscheinend braucht es ein Tupel. –

0

Anstelle von regular expressions können Sie mit der Methode endswith() überprüfen, ob eine Zeichenfolge mit einem bestimmten Muster endet.

d.h .:

for row in rows: 
    if row.endswith('DA') or row.endswith('PL'): 
     #doSomething 

Sie sollten eine andere erstellen df die gefilterten Daten eingeben und dann pd.to_csv() verwenden, um eine saubere Version der Datei zu speichern.

2

können Sie eine boolean Maske verwenden, wobei Sie überprüfen, ob die letzten beiden Zeichen von User_Name in nicht (~) sind in einem Satz von zwei Zeichen Endungen:

>>> df[~df.User_Name.str[-2:].isin(['DA', 'PA'])] 
    User_Name             DN 
2 MB424PL CN=MB424PL, CN=Users, DC=prod, DC=trovp, DC=net 
3 MBDA423  CN=MBDA423, OU=DNA, DC=prod, DC=trovp, DC=net 
4 MB2ADA4 CN=MB2ADA4, OU=DNA, DC=prod, DC=trovp, DC=nete... 
Verwandte Themen