Ausgabe
- Meine Frage ist, wie man einen Wert in eine neue Spalte einfügt, basierend auf dem Inhalt in einer anderen Spalte.
- In meinem speziellen Fall habe ich einen Datenrahmen mit einer Spalte namens
'Flop'
, die Zeichenfolgenwerte in 3 verschiedenen Kategorien enthält - Ich kann diese “Kategorien” mit Regex finden, und basierend auf jeder Kategorie möchte ich eine weitere Spalte
'Suitedness'
mit dem Namen jeder Kategorie erstellen.
Ein Beispiel für mein df ist:
import pandas as pd
df = pd.DataFrame()
df['Flop']=['As 5d 7c','As 9s 3s','8c 7d 5s','8d, As, Js','Qs Ts 8d','7s 2s 2d']
Anfänglicher Datenrahmen
Flop
As 5d 7c
As 9s 3s
8c 7d 5s
8d, As, Js
Qs Ts 8d
7s 2s 2d
Ich löse das Problem folgendermaßen:
Monotone = df[df['Flop'].str.contains('(\ws\s){2}\ws',na=False)]
Monotone['Suitedness']= 'Monotone'
Rainbow = df[df['Flop'].str.contains('(\wc\s.*)+|(\w.\s\wc.*)+|(\w[s,d,c]\s\w[s,d,c]\s\wc)+',na=False)]
Rainbow['Suitedness']= 'Rainbow'
DoubleSuited = df[df['Flop'].str.contains('((\ws\s){2}\w[d,c])+|(\ws\s\w[d,c]\s\ws)+|(\w[d,c]\s\ws\s\ws)+',na=False)]
DoubleSuited['Suitedness']= 'Double Suited'
df2 = pd.concat([Monotone,Rainbow,DoubleSuited])
df2 = df2.sort_index()
- Dieser Code erstellt 3 verschiedene Datenrahmen und verkettet sie.
- Diese Lösung funktioniert, ist aber unelegant.
- Ich suche nach einer saubereren Lösung.
- Außerdem ist meine Regex-Syntax ein wenig chaotisch.
- Die 3 Kategorien basieren auf den Buchstaben ‘s’, 1, 2 oder 3 ‘s’
- Ich hätte auch gerne Tipps zur besseren Regex-Syntax.
Endgültiger Datenrahmen
Flop Suitedness
As 5d 7c Rainbow
As 9s 3s Monotone
8c 7d 5s Rainbow
Qs Ts 8d Double Suited
7s 2s 2d Double Suited
Lösung
- Verwenden Ihrer Beispieldaten
- Diese Lösung ändert nicht die verwendeten regulären Ausdrücke, sondern optimiert nur die Einstellung der
'Suitedness'
einzelnen Zeichenfolgen'Flop'
- Im SO: Regex-Tag-Wiki finden Sie Ideen, wie Sie die regulären Ausdrücke effizienter gestalten können
- Besuchen Sie regex101 , um Ihre regulären Ausdrücke zu testen.
- Erstellen Sie ein Wörterbuch mit Ihren regulären Ausdrücken und zugehörigen Phrasen
- Verwenden Sie pandas.Series.apply mit einem Listenverständnis, das eine Liste mit der richtigen
Suitedness
oder eine leere Liste zurückgibt, wenn es keine Übereinstimmung mit gibtre.match
.
- Mit der Erwartung, dass es nur eine einzige Übereinstimmung oder keine Übereinstimmung geben wird, wird pandas.Series.explode verwendet, um den Wert bei Index 0 zurückzugeben.
- Eine Listenindexauswahl funktioniert nicht für Fälle, in denen die Liste leer ist (z. B.
[][0]
), da dies zu einem führtIndexError
- Eine Listenindexauswahl funktioniert nicht für Fälle, in denen die Liste leer ist (z. B.
- Mit der Erwartung, dass es nur eine einzige Übereinstimmung oder keine Übereinstimmung geben wird, wird pandas.Series.explode verwendet, um den Wert bei Index 0 zurückzugeben.
- Wenn Sie sich nicht mit
NaN
Werten befassen, verwenden Siedf = df.dropna()
, um diese Zeilen zu entfernen.
import pandas as pd
import re
# create a dict of mappings
mapping = {'(\ws\s){2}\ws': 'Monotone',
'(\wc\s.*)+|(\w.\s\wc.*)+|(\w[s,d,c]\s\w[s,d,c]\s\wc)+': 'Rainbow',
'((\ws\s){2}\w[d,c])+|(\ws\s\w[d,c]\s\ws)+|(\w[d,c]\s\ws\s\ws)+': 'Double Suited'}
# apply a list comprehension
df['Suitedness'] = df.Flop.apply(lambda x: [v for k, v in mapping.items() if re.match(k, x)]).explode()
# display(df)
Flop Suitedness
As 5d 7c Rainbow
As 9s 3s Monotone
8c 7d 5s Rainbow
8d, As, Js NaN
Qs Ts 8d Double Suited
7s 2s 2d Double Suited
Beantwortet von – Trenton McKinney
Antwort geprüft von – Marie Seifert (FixError Admin)