Szukam skutecznego sposobu na usunięcie niechcianych części z ciągów w kolumnie DataFrame.
Dane wyglądają następująco:
time result
1 09:00 +52A
2 10:00 +62B
3 11:00 +44a
4 12:00 +30b
5 13:00 -110a
Muszę przyciąć te dane do:
time result
1 09:00 52
2 10:00 62
3 11:00 44
4 12:00 30
5 13:00 110
Próbowałem .str.lstrip('+-')
i. str.rstrip('aAbBcC')
, ale pojawił się błąd:
TypeError: wrapper() takes exactly 1 argument (2 given)
Wszelkie wskazówki byłyby bardzo mile widziane!
Sześć lat po opublikowaniu pierwotnego pytania pandy mają teraz dużą liczbę „wektoryzowanych” funkcji ciągów, które mogą zwięźle wykonywać te operacje na łańcuchach.
Ta odpowiedź pozwoli zbadać niektóre z tych funkcji ciągów, zasugerować szybsze alternatywy, a na końcu przejdzie do porównania czasów.
.str.replace
Określ podciąg / wzorzec do dopasowania oraz podciąg, którym ma zostać zastąpiony.
Jeśli potrzebujesz konwersji wyniku na liczbę całkowitą, możesz użyć
Series.astype
,Jeśli nie chcesz modyfikować
df
w miejscu, użyjDataFrame.assign
:.str.extract
Przydatne do wyodrębniania podciągów, które chcesz zachować.
W
extract
przypadku należy określić przynajmniej jedną grupę przechwytywania.expand=False
zwróci serię z przechwyconymi przedmiotami z pierwszej grupy przechwytywania..str.split
i.str.get
Dzielenie działa przy założeniu, że wszystkie struny mają tę spójną strukturę.
Nie polecaj, jeśli szukasz ogólnego rozwiązania.
Optymalizacja: listy składane
W pewnych okolicznościach listy składane powinny być preferowane w stosunku do funkcji łańcuchowych pandy. Powodem jest to, że funkcje łańcuchowe są z natury trudne do wektoryzacji (w prawdziwym tego słowa znaczeniu), więc większość funkcji ciągów i wyrażeń regularnych jest tylko opakowaniem wokół pętli z większym narzutem.
Mój opis: Czy pętle for w pandach są naprawdę złe? Kiedy powinno mnie to obchodzić?, omawia bardziej szczegółowo.
str.replace
Opcja może być ponownie napisane przy użyciure.sub
str.extract
Przykładem może być ponownie napisane przy użyciu wyrażeń listowych zre.search
,Jeśli istnieje możliwość uzyskania wartości NaN lub braku dopasowań, konieczne będzie ponowne napisanie powyższego, aby uwzględnić sprawdzanie błędów. Robię to za pomocą funkcji.
Możemy również przepisać odpowiedzi @ eumiro i @ MonkeyButter, używając wyrażeń listowych:
I,
Obowiązują te same zasady obsługi NaN itp.
Porównanie wydajności
Wykresy generowane za pomocą perfplot . Pełna lista kodów w celach informacyjnych.Odpowiednie funkcje są wymienione poniżej.
Niektóre z tych porównań są niesprawiedliwe, ponieważ wykorzystują strukturę danych OP, ale wyciągają z nich to, co chcesz. Należy zauważyć, że każda funkcja rozumienia listy jest szybsza lub porównywalna niż jej odpowiednik w wersji pandy.
Funkcje
źródło
Try using .loc[row_indexer,col_indexer] = value instead
użyłbym funkcji zamiany pandy, bardzo prostej i potężnej, ponieważ możesz użyć wyrażenia regularnego. Poniżej używam wyrażenia regularnego \ D, aby usunąć wszelkie znaki niebędące cyframi, ale oczywiście można uzyskać całkiem kreatywny wynik z wyrażeniem regularnym.
źródło
df.loc[:, 'column_a'].replace(regex=True, to_replace="my_prefix", value="new_prefix")
. Spowoduje to konwersję ciągu, takiego jak „my_prefixaaa” na „new_prefixaaa”.W szczególnym przypadku, gdy znasz liczbę pozycji, które chcesz usunąć z kolumny dataframe, możesz użyć indeksowania ciągów wewnątrz funkcji lambda, aby pozbyć się tych części:
Ostatni znak:
Pierwsze dwa znaki:
źródło
Występuje tu błąd: obecnie nie można przekazywać argumentów do
str.lstrip
istr.rstrip
:http://github.com/pydata/pandas/issues/2411
EDYCJA: 2012-12-07 to działa teraz w gałęzi deweloperów:
źródło
Bardzo prostą metodą byłoby użycie
extract
metody do wybrania wszystkich cyfr. Po prostu podaj wyrażenie regularne,'\d+'
które wyodrębni dowolną liczbę cyfr.źródło
Często używam list składanych do tego typu zadań, ponieważ często są one szybsze.
Mogą występować duże różnice w wydajności między różnymi metodami wykonywania takich czynności (tj. Modyfikowania każdego elementu serii w ramach DataFrame). Często zrozumienie listy może być najszybsze - zobacz poniższy wyścig kodu dotyczący tego zadania:
źródło
Przypuśćmy, że twój DF ma te dodatkowe znaki między liczbami. Ostatni wpis.
Możesz spróbować str.replace, aby usunąć znaki nie tylko z początku i końca, ale także pomiędzy.
Wynik:
źródło
Spróbuj tego, używając wyrażenia regularnego:
źródło