Mam taką serię po wykonaniu funkcji Groupby („name”) i użyciu funkcji mean () w innej kolumnie
name
383 3.000000
663 1.000000
726 1.000000
737 9.000000
833 8.166667
Czy ktoś mógłby mi pokazać, jak odfiltrować wiersze z wartościami średnimi 1,000000? Dziękuję i bardzo doceniam twoją pomoc.
Odpowiedzi:
In [5]: import pandas as pd test = { 383: 3.000000, 663: 1.000000, 726: 1.000000, 737: 9.000000, 833: 8.166667 } s = pd.Series(test) s = s[s != 1] s Out[0]: 383 3.000000 737 9.000000 833 8.166667 dtype: float64
źródło
s
a następnie dwukrotnie używać w wyrażeniu). Działa jednak tylko od pand 0.18.Od wersji pandy 0.18+ filtrowanie serii można również wykonać w sposób przedstawiony poniżej
test = { 383: 3.000000, 663: 1.000000, 726: 1.000000, 737: 9.000000, 833: 8.166667 } pd.Series(test).where(lambda x : x!=1).dropna()
Zamówienie: http://pandas.pydata.org/pandas-docs/version/0.18.1/whatsnew.html#method-chaininng-improvements
źródło
Jak zauważył DACW , istnieją ulepszenia dotyczące łączenia metod metod, które bardzo ładnie robią to, czego szukasz.
Zamiast używać
.where
, możesz przekazać swoją funkcję do.loc
indeksatora lub indeksatora serii[]
i uniknąć wywołania.dropna
:test = pd.Series({ 383: 3.000000, 663: 1.000000, 726: 1.000000, 737: 9.000000, 833: 8.166667 }) test.loc[lambda x : x!=1] test[lambda x: x!=1]
Podobne zachowanie jest obsługiwane w klasach DataFrame i NDFrame.
źródło
Szybkim sposobem na zrobienie tego jest rekonstrukcja przy użyciu
numpy
do wycinania bazowych tablic. Zobacz czasy poniżej.mask = s.values != 1 pd.Series(s.values[mask], s.index[mask]) 0 383 3.000000 737 9.000000 833 8.166667 dtype: float64
naiwne wyczucie czasu
źródło
Innym sposobem jest najpierw konwersja do DataFrame i użycie metody zapytania (zakładając, że masz zainstalowany numexpr):
import pandas as pd test = { 383: 3.000000, 663: 1.000000, 726: 1.000000, 737: 9.000000, 833: 8.166667 } s = pd.Series(test) s.to_frame(name='x').query("x != 1")
źródło
Jeśli lubisz operację łańcuchową, możesz również użyć
compress
funkcji:test = pd.Series({ 383: 3.000000, 663: 1.000000, 726: 1.000000, 737: 9.000000, 833: 8.166667 }) test.compress(lambda x: x != 1) # 383 3.000000 # 737 9.000000 # 833 8.166667 # dtype: float64
źródło
W moim przypadku miałem serię pand, w której wartościami są krotki znaków :
Out[67] 0 (H, H, H, H) 1 (H, H, H, T) 2 (H, H, T, H) 3 (H, H, T, T) 4 (H, T, H, H)
Dlatego mogłem użyć indeksowania do filtrowania serii, ale do utworzenia indeksu potrzebowałem
apply
. Mój warunek to „znajdź wszystkie krotki, które mają dokładnie jedno 'H'”.series_of_tuples[series_of_tuples.apply(lambda x: x.count('H')==1)]
Przyznaję, że nie można go „łączyć w łańcuch” (tj. Zauważ, że powtarzam
series_of_tuples
dwa razy; musisz przechowywać dowolną tymczasową serię w zmiennej, aby móc wywołać na niej (...)).Mogą istnieć również inne metody (poza
.apply(...)
), które mogą działać elementarnie, aby utworzyć indeks boolowski.Wiele innych odpowiedzi (w tym zaakceptowana odpowiedź) przy użyciu funkcji łańcuchowych, takich jak:
.compress()
.where()
.loc[]
[]
Akceptują wywołania (lambdy), które są stosowane do serii , a nie do poszczególnych wartości w tych seriach!
Dlatego moja seria krotek zachowywała się dziwnie, gdy próbowałem użyć powyższego warunku / wywoływanej / lambda, z dowolną funkcją łańcuchową, taką jak
.loc[]
:series_of_tuples.loc[lambda x: x.count('H')==1]
Powoduje błąd:
KeyError: „Poziom H musi być taki sam jak nazwa (brak)”
Byłem bardzo zdezorientowany, ale wydaje mi się, że używa
series_of_tuples.count(...)
funkcji Series.count , co nie jest tym, czego chciałem.Przyznaję, że alternatywna struktura danych może być lepsza:
Tworzy to serię ciągów (np. Przez konkatenację krotki; łączenie znaków w krotce w jednym ciągu)
series_of_tuples.apply(''.join)
Więc mogę wtedy użyć łańcucha
Series.str.count
series_of_tuples.apply(''.join).str.count('H')==1
źródło