Forum: PC-Programmierung Python - Suchfunktion


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Hannibal (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Regex rules

von Hannibal (Gast)


Bewertung
0 lesenswert
nicht 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)


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

von Hannibal (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Dann nimmst du '&' was das elementweise und ist...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.