Ich suche nach einer effizienten Möglichkeit, unerwünschte Teile aus Zeichenfolgen in einer DataFrame-Spalte zu entfernen.
Daten sehen aus wie:
time result
1 09:00 +52A
2 10:00 +62B
3 11:00 +44a
4 12:00 +30b
5 13:00 -110a
Ich muss diese Daten kürzen, um:
time result
1 09:00 52
2 10:00 62
3 11:00 44
4 12:00 30
5 13:00 110
Ich habe es versucht .str.lstrip('+-')
und. str.rstrip('aAbBcC')
, habe aber einen Fehler bekommen:
TypeError: wrapper() takes exactly 1 argument (2 given)
Alle Hinweise wäre sehr dankbar!
6 Jahre nachdem die ursprüngliche Frage veröffentlicht wurde, verfügt Pandas nun über eine gute Anzahl von "vektorisierten" Zeichenfolgenfunktionen, mit denen diese Zeichenfolgenmanipulationsoperationen kurz und bündig ausgeführt werden können.
In dieser Antwort werden einige dieser Zeichenfolgenfunktionen untersucht, schnellere Alternativen vorgeschlagen und am Ende ein Zeitvergleich durchgeführt.
.str.replace
Geben Sie den passenden Teilstring / das passende Muster und den zu ersetzenden Teilstring an.
Wenn Sie das Ergebnis in eine Ganzzahl konvertieren möchten, können Sie Folgendes verwenden
Series.astype
:Wenn Sie nicht direkt ändern möchten
df
, verwenden SieDataFrame.assign
:.str.extract
Nützlich zum Extrahieren der Teilzeichenfolge (n), die Sie behalten möchten.
Mit
extract
muss mindestens eine Erfassungsgruppe angegeben werden.expand=False
gibt eine Serie mit den erfassten Elementen aus der ersten Erfassungsgruppe zurück..str.split
und.str.get
Das Teilen funktioniert unter der Annahme, dass alle Ihre Zeichenfolgen dieser konsistenten Struktur folgen.
Nicht empfehlen, wenn Sie nach einer allgemeinen Lösung suchen.
Optimieren: Listenverständnisse
Unter bestimmten Umständen sollte das Listenverständnis den Pandas-String-Funktionen vorgezogen werden. Der Grund dafür ist, dass Zeichenfolgenfunktionen von Natur aus schwer zu vektorisieren sind (im wahrsten Sinne des Wortes), sodass die meisten Zeichenfolgen- und Regex-Funktionen nur Wrapper um Schleifen mit mehr Overhead sind.
Mein Artikel: Sind For-Loops bei Pandas wirklich schlecht? Wann sollte es mich interessieren? geht näher darauf ein.
Die
str.replace
Option kann mit neu geschrieben werdenre.sub
Das
str.extract
Beispiel kann unter Verwendung eines Listenverständnisses mitre.search
, neu geschrieben werden .Wenn NaNs oder Nichtübereinstimmungen möglich sind, müssen Sie die obigen Informationen neu schreiben, um eine Fehlerprüfung einzuschließen. Ich mache das mit einer Funktion.
Wir können die Antworten von @ eumiro und @ MonkeyButter auch mithilfe von Listenverständnissen neu schreiben:
Und,
Es gelten die gleichen Regeln für den Umgang mit NaNs usw.
Leistungsvergleich
Mit Perfplot erzeugte Diagramme . Vollständige Codeliste als Referenz. Die relevanten Funktionen sind unten aufgeführt.
Einige dieser Vergleiche sind unfair, weil sie die Struktur der OP-Daten ausnutzen, aber daraus entnehmen, was Sie wollen. Zu beachten ist, dass jede Listenverständnisfunktion entweder schneller oder vergleichbar ist als die entsprechende Pandas-Variante.
Funktionen
quelle
Try using .loc[row_indexer,col_indexer] = value instead
Ich würde die Pandas-Ersetzungsfunktion verwenden, sehr einfach und leistungsstark, da Sie Regex verwenden können. Unten verwende ich den regulären Ausdruck \ D, um nichtstellige Zeichen zu entfernen, aber natürlich könnten Sie mit dem regulären Ausdruck ziemlich kreativ werden.
quelle
df.loc[:, 'column_a'].replace(regex=True, to_replace="my_prefix", value="new_prefix")
. Dadurch wird eine Zeichenfolge wie "my_prefixaaa" in "new_prefixaaa" konvertiert.In dem speziellen Fall, in dem Sie die Anzahl der Positionen kennen, die Sie aus der Datenrahmenspalte entfernen möchten, können Sie die Zeichenfolgenindizierung innerhalb einer Lambda-Funktion verwenden, um diese Teile zu entfernen:
Letzter Charakter:
Die ersten beiden Zeichen:
quelle
Hier gibt es einen Fehler: Derzeit können keine Argumente an
str.lstrip
und übergeben werdenstr.rstrip
:http://github.com/pydata/pandas/issues/2411
EDIT: 2012-12-07 das funktioniert jetzt auf dem dev branch:
quelle
Eine sehr einfache Methode wäre die Verwendung der
extract
Methode zur Auswahl aller Ziffern. Geben Sie einfach den regulären Ausdruck ein,'\d+'
der eine beliebige Anzahl von Ziffern extrahiert.quelle
Ich verwende häufig Listenverständnisse für diese Art von Aufgaben, weil sie oft schneller sind.
Es kann große Leistungsunterschiede zwischen den verschiedenen Methoden geben, um solche Dinge zu tun (dh jedes Element einer Reihe innerhalb eines DataFrame zu ändern). Oft kann ein Listenverständnis am schnellsten sein - siehe Code Race unten für diese Aufgabe:
quelle
Angenommen, Ihr DF hat diese zusätzlichen Zeichen auch zwischen den Zahlen. Der letzte Eintrag.
Sie können versuchen, str.replace zu verwenden, um Zeichen nicht nur von Anfang und Ende, sondern auch von dazwischen zu entfernen.
Ausgabe:
quelle
Versuchen Sie dies mit einem regulären Ausdruck:
quelle