Mam pand DataFrame i chcę usunąć z niej wiersze, w których długość ciągu w określonej kolumnie jest większa niż 2.
Oczekuję, że będę w stanie to zrobić (według tej odpowiedzi ):
df[(len(df['column name']) < 2)]
ale dostaję błąd:
KeyError: u'no item named False'
Co ja robię źle?
(Uwaga: Wiem, że mogę df.dropna()
się pozbyć wierszy zawierających takie wiersze NaN
, ale nie widziałem, jak usunąć wiersze na podstawie wyrażenia warunkowego).
df[[(len(x) < 2) for x in df['column name']]]
ale twój jest o wiele ładniejszy. Dzięki za pomoc!df[df['column name'].map(lambda x: str(x)!=".")]
pandas 0.23.4
i python 3.6.copy()
na końcu, na wypadek gdybyś chciał później edytować tę ramkę danych (na przykład przypisanie nowych kolumn spowodowałoby podniesienie ostrzeżenia „Próbuję ustawić wartość na kopii wycinka z DataFrame”.Aby bezpośrednio odpowiedzieć na pierwotny tytuł tego pytania „Jak usunąć wiersze z pandy DataFrame na podstawie wyrażenia warunkowego” (co, jak rozumiem, niekoniecznie jest problemem OP, ale może pomóc innym użytkownikom napotkanym na to pytanie) jednym ze sposobów na to jest użycie spadek sposób:
df = df.drop(some labels)
df = df.drop(df[<some boolean condition>].index)
Przykład
Aby usunąć wszystkie wiersze, w których wynik „kolumny” wynosi <50:
df = df.drop(df[df.score < 50].index)
Wersja na miejscu (jak wskazano w komentarzach)
df.drop(df[df.score < 50].index, inplace=True)
Wiele warunków
(patrz Indeksowanie boolowskie )
Aby usunąć wszystkie wiersze, w których kolumna „score” wynosi <50 i> 20
df = df.drop(df[(df.score < 50) & (df.score > 20)].index)
źródło
reset_index()
). Przekonałem się o tym na własnej skórze, gdy z mojej ramki danych spadła droga do wielu wierszy.test = df.drop(df[df['col1'].dtype == str].index)
, ale pojawia się błądKeyError: False
Próbowałem równieżdf.drop(df[df.col1.dtype == str].index)
idf.drop(df[type(df.cleaned_norm_email) == str].index)
ale nic nie wydaje się do pracy? Czy ktoś może doradzić. Dzięki! @ Użytkownikdf[(df.score < 50) & (df.score > 20)]
jako część swojej odpowiedzi. Jeśli to zrobiszdf = df[(df.score >= 50) | (df.score <= 20)]
, uzyskasz odpowiedź znacznie szybciej.Możesz przypisać
DataFrame
do odfiltrowanej wersji samego siebie:Jest to szybsze niż
drop
:źródło
Rozwijam ogólne rozwiązanie @ User, aby zapewnić
drop
bezpłatną alternatywę. Dotyczy to osób skierowanych tutaj na podstawie tytułu pytania (nie problemu OP)Powiedz, że chcesz usunąć wszystkie wiersze z wartościami ujemnymi. Jednym rozwiązaniem liniowym jest:
Krok po kroku Objaśnienie: -
Wygenerujmy losową ramkę danych o rozkładzie normalnym 5x5
Niech warunek usunie negatywne. Wartość logiczna df spełniająca warunek:
Szereg boolowski dla wszystkich wierszy spełniających warunek Uwaga: jeśli dowolny element w wierszu nie spełni warunku, wiersz zostanie oznaczony jako fałsz
Na koniec odfiltruj wiersze z ramki danych na podstawie warunku
Możesz przypisać go z powrotem do df, aby faktycznie usunąć vs filtr wykonane powyżej
df = df[(df > 0).all(axis=1)]
Można to łatwo rozszerzyć, aby odfiltrować wiersze zawierające NaN (wpisy nienumeryczne): -
df = df[(~df.isnull()).all(axis=1)]
Można to również uprościć dla przypadków takich jak: Usuń wszystkie wiersze, w których kolumna E jest ujemna
Chciałbym zakończyć niektórymi statystykami profilowania, dlaczego
drop
rozwiązanie @ User jest wolniejsze niż filtrowanie oparte na surowej kolumnie: -Kolumna jest w zasadzie
Series
czyliNumPy
tablica może być indeksowane bez żadnych kosztów. Dla osób zainteresowanych tym, w jaki sposób podstawowa organizacja pamięci odgrywa rolę w szybkości wykonywania, tutaj jest świetne łącze na temat przyspieszania pand :źródło
W pandach możesz wykonać
str.len
granicę i użyć wyniku logicznego do jej przefiltrowania.źródło
Jeśli chcesz upuścić wiersze ramki danych na podstawie jakiegoś skomplikowanego warunku na wartość kolumny, wówczas zapisanie tego w sposób pokazany powyżej może być skomplikowane. Mam następujące prostsze rozwiązanie, które zawsze działa. Załóżmy, że chcesz upuścić kolumnę z nagłówkiem, więc najpierw umieść tę kolumnę na liście.
teraz zastosuj jakąś funkcję do każdego elementu listy i umieść ją w serii panda:
w moim przypadku po prostu starałem się uzyskać liczbę tokenów:
teraz dodaj jedną dodatkową kolumnę z powyższą serią w ramce danych:
teraz możemy zastosować warunek w nowej kolumnie, taki jak:
źródło