Forum: PC-Programmierung Python - Suchfunktion


von Hannibal (Gast)


Lesenswert?

Moin,

ich hätte eine Expertenfrage zum Thema Python. Ich habe eine csv-Datei 
mit mehreren Zeilen. Die Spalten an sich sind durch Kommas getrennt.

z.B.: ID, NAME, BESCHREIBUNG xyz abcd, KOMMENTAR

Mit folgender Funktion durchsuche ich die einzelnen "Spalten", um nur 
die Zeilen zu filtern, die von Interesse sind:
1
df_rest = pd.DataFrame(df_rest[df_rest[[0,1,2,3]].apply(lambda r: r.str.contains(search_keywords, case=False).any(), axis=1)])

search_keywords kann z.B. sein: NAME_X | NAME_y (Das "|"Zeichen ist 
anscheinend Pflicht :) )

Es werden somit all die Zeilen gefiltert, die einen der Namen enthalten. 
Gibt es eine Möglichkeit, um nur die Zeilen zu filtern, die z.B. mehrere 
Strings enthalten: z.B. NAME_X&ID_X | NNAME_y&KOMMENTAR_y  ?

Besten Dank

von Yalu X. (yalu) (Moderator)


Lesenswert?

Deine Frage bezieht sich zunächst nur indirekt auf Python, da du Pandas
zu verwenden scheinst. Damit kenne ich mich auch nicht aus. Wenn man
aber erst einmal weiß, dass es um Pandas geht, findet man auch schnell
die Dokumentation dazu.

Die Methode contains ist hier beschrieben:

  https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.str.contains.html#pandas.Series.str.contains

Das Argument pat darf also einen regulären Ausdruck enthalten. Zur
Verarbeitung regulären Ausdrücke wird die re-Bibliothek von Python
verwendet, die hier (Python 2)

  https://docs.python.org/2/library/re.html

bzw. hier (Python 3)

  https://docs.python.org/3/library/re.html

beschrieben ist. Neben dem |-Operator sind also noch sehr viele weitere
Dinge möglich, um die Suche zu spezifizieren.

von Florian F. (flof3000)


Lesenswert?

df.apply(lambda...) gibt dir ein DataFrame voller Bools zurueck, die 
kannst du kurzerhand mit '|' verknuepfen, und dann mit any(axis=1) auf 
'welche Zeilen haetten's denn gerne' konvertieren.

also:
1
df_rest[
2
  (df_rest[[0,1,]].apply(lambda r: r.str.contains('x', case=False)) | 
3
   df_rest[[0,1,]].apply(lambda r: r.str.contains('a', case=False))
4
  ).any(axis=1)]
Warum du da noch mal ein pd.DataFrame drum strickst ist mir unklar.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Nachtrag zu meinem Beitrag oben:

Hannibal schrieb:
> z.B. NAME_X&ID_X | NNAME_y&KOMMENTAR_y  ?

Willst du NAME_x und NAME_y nur in der Namensspalte, ID_X nur in der
ID-Spalte und KOMMENTAR_y nur in der Kommentarspalte suchen?

Dann geht es wohl eher in die von Florian beschriebenen Richtung: Du
führst nacheinander mehrere Einzelsuchen in den betreffenden Spalten
durch und verknüpfst deren Ergebnisse mittels boolescher Operationen.

von ui (Gast)


Lesenswert?

Regex rules

von Hannibal (Gast)


Lesenswert?

Das Problem ist, wenn ich nach mehreren Strings suche wie z.B. mittels
1
df_rest = pd.DataFrame(df_rest[df_rest[[0,1,2,3,4,5]].apply(lambda r: (r.str.contains('OpenSSL', case=False).any()) and (r.str.contains('0.9.4 ', case=False).any()), axis=1)])

werden diese Meldungen zwar gefilter, aber anscheinend gibt es bei 
Strings mit einem oder mehreren Punkten wie Versionsnummern Probleme. Es 
wird nicht nur Zeile mit "OpenSSL 0.9.4" gefiltert sondern auch "OpenSSL 
0.9.7". Anscheinend bewirkt der Punkt eine Art oder Verknüpfung ???

von Florian F. (flof3000)


Lesenswert?

and ist hier voellig falsch - das verknuepft zwei 'Werte' zu einem 
bool. Du brauchst & oder |, welche elementweise arbeiten.

von Hannibal (Gast)


Lesenswert?

Dann werden alle Zeilen, die X oder Y besitzen, gefilter, das möchte ich 
eben nicht. Sondern alle Zeilen, doie beide Werte besitzen.

von Florian F. (flof3000)


Lesenswert?

Dann nimmst du '&' was das elementweise und ist...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.