Zwróć uwagę na nawiasy. Ze względu na reguły pierwszeństwa operatora Pythona , &wiązania są ściślejsze niż <=i >=. Dlatego nawiasy w ostatnim przykładzie są konieczne. Bez nawiasów
Aby wybrać wiersze, których wartość kolumny nie jest równasome_value , użyj !=:
df.loc[df['column_name']!= some_value]
isinZwraca wartość logiczną z serii, tak aby wybrać wiersze, których wartość jest nie w some_values, neguje logiczną Series przy użyciu ~:
df.loc[~df['column_name'].isin(some_values)]
Na przykład,
import pandas as pd
import numpy as np
df = pd.DataFrame({'A':'foo bar foo bar foo bar foo foo'.split(),'B':'one one two three two two one three'.split(),'C': np.arange(8),'D': np.arange(8)*2})print(df)# A B C D# 0 foo one 0 0# 1 bar one 1 2# 2 foo two 2 4# 3 bar three 3 6# 4 foo two 4 8# 5 bar two 5 10# 6 foo one 6 12# 7 foo three 7 14print(df.loc[df['A']=='foo'])
daje
A B C D
0 foo one 002 foo two 244 foo two 486 foo one 6127 foo three 714
Jeśli masz wiele wartości, które chcesz uwzględnić, umieść je na liście (lub bardziej ogólnie, dowolne iterowalne) i użyj isin:
print(df.loc[df['B'].isin(['one','three'])])
daje
A B C D
0 foo one 001 bar one 123 bar three 366 foo one 6127 foo three 714
Pamiętaj jednak, że jeśli chcesz to zrobić wiele razy, bardziej efektywne jest najpierw utworzenie indeksu, a następnie użycie df.loc:
df = df.set_index(['B'])print(df.loc['one'])
daje
A C D
B
one foo 00
one bar 12
one foo 612
lub, aby dołączyć wiele wartości z indeksu, użyj df.index.isin:
df.loc[df.index.isin(['one','two'])]
daje
A C D
B
one foo 00
one bar 12
two foo 24
two foo 48
two bar 510
one foo 612
W rzeczywistości df [df ['nazwa_kolumny]] == jakaś_wartość] również działa. Ale moja pierwsza próba, df.where (df ['colume_name'] == some_value) nie działa ... nie jestem pewien, dlaczego ...
szli
13
Podczas używania df.where(condition)warunek musi mieć taki sam kształt jak df.
Skoro df[df['column_name'] == some_value]działa, dlaczego potrzebujemy .loctutaj dodać ?
qqqwww,
311
Istnieje kilka sposobów wybierania wierszy z ramki danych pand:
Indeksowanie boolowskie ( df[df['col'] == value])
Indeksowanie pozycyjne ( df.iloc[...])
Indeksowanie etykiet ( df.xs(...))
df.query(...) API
Poniżej pokazuję przykłady każdego z nich wraz z radą, kiedy stosować określone techniki. Załóżmy, że naszym kryterium jest kolumna 'A'=='foo'
(Uwaga na temat wydajności: w przypadku każdego typu podstawowego możemy uprościć sprawę, używając interfejsu API pand lub możemy wyjść poza interfejs API, zwykle w celu numpyprzyspieszenia.)
Konfiguracja
Pierwszą rzeczą, której potrzebujemy, jest określenie warunku, który będzie naszym kryterium wyboru wierszy. Zaczniemy od przypadku OP column_name == some_valuei dołączymy kilka innych typowych przypadków użycia.
Pożyczanie od @unutbu:
import pandas as pd, numpy as np
df = pd.DataFrame({'A':'foo bar foo bar foo bar foo foo'.split(),'B':'one one two three two two one three'.split(),'C': np.arange(8),'D': np.arange(8)*2})
1. Indeksowanie boolowskie
... Indeksowanie boolowskie wymaga znalezienia prawdziwej wartości 'A'kolumny każdego wiersza równej 'foo', a następnie użycia tych wartości prawdy do zidentyfikowania, które wiersze zachować. Zazwyczaj chcielibyśmy nazwać tej serii tablicę wartości prawdę mask. Zrobimy to również tutaj.
mask = df['A']=='foo'
Następnie możemy użyć tej maski do wycinania lub indeksowania ramki danych
df[mask]
A B C D
0 foo one 002 foo two 244 foo two 486 foo one 6127 foo three 714
Jest to jeden z najprostszych sposobów wykonania tego zadania, a jeśli wydajność lub intuicyjność nie stanowią problemu, powinna to być wybrana metoda. Jeśli jednak wydajność stanowi problem, warto rozważyć alternatywny sposób utworzenia pliku mask.
2. Indeksowanie pozycji
Indeksowanie pozycyjne ( df.iloc[...]) ma swoje przypadki użycia, ale nie jest to jeden z nich. Aby określić, gdzie należy kroić, najpierw musimy wykonać tę samą analizę boolowską, którą wykonaliśmy powyżej. To pozostawia nam jeden dodatkowy krok do wykonania tego samego zadania.
mask = df['A']=='foo'
pos = np.flatnonzero(mask)
df.iloc[pos]
A B C D
0 foo one 002 foo two 244 foo two 486 foo one 6127 foo three 714
3. Indeksowanie etykiet
Indeksowanie etykiet może być bardzo przydatne, ale w tym przypadku ponownie wykonujemy więcej pracy bez żadnych korzyści
df.set_index('A', append=True, drop=False).xs('foo', level=1)
A B C D
0 foo one 002 foo two 244 foo two 486 foo one 6127 foo three 714
4. df.query()API
pd.DataFrame.queryjest bardzo eleganckim / intuicyjnym sposobem wykonania tego zadania, ale często jest wolniejszy. Jednakże , jeśli zwrócić uwagę na czasy poniżej, dla dużych danych, zapytanie jest bardzo wydajny. Bardziej niż standardowe podejście i podobnej wielkości jak moja najlepsza sugestia.
df.query('A == "foo"')
A B C D
0 foo one 002 foo two 244 foo two 486 foo one 6127 foo three 714
Preferuję używanie Booleanmask
Rzeczywistych ulepszeń można dokonać, modyfikując sposób, w jaki tworzymy nasze Booleanmask.
maskalternatywa 1 Użyj podstawowej numpytablicy i zrezygnuj z narzutów związanych z tworzeniem kolejnejpd.Series
mask = df['A'].values =='foo'
Na końcu pokażę pełniejsze testy czasowe, ale spójrzmy tylko na wzrost wydajności, jaki uzyskujemy dzięki przykładowej ramce danych. Najpierw przyjrzymy się różnicy w tworzeniumask
%timeit mask = df['A'].values =='foo'%timeit mask = df['A']=='foo'5.84µs ±195 ns per loop (mean ± std. dev. of 7 runs,100000 loops each)166µs ±4.45µs per loop (mean ± std. dev. of 7 runs,10000 loops each)
Ocena za maskpomocą numpytablicy jest ~ 30 razy szybsza. Wynika to częściowo z tego, że numpyocena jest często szybsza. Wynika to również częściowo z braku narzutu niezbędnego do zbudowania indeksu i odpowiedniego pd.Seriesobiektu.
Następnie przyjrzymy się terminowi krojenia z jednym maskna drugi.
mask = df['A'].values =='foo'%timeit df[mask]
mask = df['A']=='foo'%timeit df[mask]219µs ±12.3µs per loop (mean ± std. dev. of 7 runs,1000 loops each)239µs ±7.03µs per loop (mean ± std. dev. of 7 runs,1000 loops each)
Wzrost wydajności nie jest tak wyraźny. Zobaczymy, czy to wytrzyma bardziej szczegółowe testy.
maskalternatywa 2
Mogliśmy również zrekonstruować ramkę danych. Podczas odtwarzania ramki danych istnieje duże zastrzeżenie - musisz się tym zająćdtypes to zrobić!
Jeśli ramka danych jest typu mieszanego, jak w naszym przykładzie, to kiedy otrzymamy df.valueswynikową tablicę, będzie ona dtypeobjectzawierała wszystkie kolumny nowej ramki danych dtypeobject. Wymaga to astype(df.dtypes)i zabija wszelkie potencjalne przyrosty wydajności.
%timeit df[m]%timeit pd.DataFrame(df.values[mask], df.index[mask], df.columns).astype(df.dtypes)216µs ±10.4µs per loop (mean ± std. dev. of 7 runs,1000 loops each)1.43 ms ±39.6µs per loop (mean ± std. dev. of 7 runs,1000 loops each)
Jeśli jednak ramka danych nie jest typu mieszanego, jest to bardzo przydatny sposób na zrobienie tego.
Dany
np.random.seed([3,1415])
d1 = pd.DataFrame(np.random.randint(10, size=(10,5)), columns=list('ABCDE'))
d1
A B C D E
002738170686202049373243436774553759687647762665828758947615
%%timeit
mask = d1['A'].values ==7
d1[mask]179µs ±8.73µs per loop (mean ± std. dev. of 7 runs,10000 loops each)
Przeciw
%%timeit
mask = d1['A'].values ==7
pd.DataFrame(d1.values[mask], d1.index[mask], d1.columns)87µs ±5.12µs per loop (mean ± std. dev. of 7 runs,10000 loops each)
Skróciliśmy czas o połowę.
maskalternatywa 3
@unutbu pokazuje również, jak używać pd.Series.isindo rozliczania każdego elementu df['A']znajdującego się w zbiorze wartości. To ocenia to samo, jeśli nasz zestaw wartości jest zbiorem jednej wartości, a mianowicie 'foo'. Ale uogólnia również, aby w razie potrzeby uwzględnić większe zestawy wartości. Okazuje się, że wciąż jest to dość szybkie, mimo że jest to bardziej ogólne rozwiązanie. Jedyną prawdziwą stratą jest intuicyjność dla tych, którzy nie znają tej koncepcji.
mask = df['A'].isin(['foo'])
df[mask]
A B C D
0 foo one 002 foo two 244 foo two 486 foo one 6127 foo three 714
Jednak, jak poprzednio, możemy wykorzystać numpydo poprawy wydajności, poświęcając praktycznie nic. Użyjemynp.in1d
mask = np.in1d(df['A'].values,['foo'])
df[mask]
A B C D
0 foo one 002 foo two 244 foo two 486 foo one 6127 foo three 714
Czas
uwzględnię również inne pojęcia wymienione w innych postach w celach informacyjnych. Kod poniżej
Każda kolumna w tej tabeli reprezentuje ramkę danych o innej długości, w której testujemy każdą funkcję. Każda kolumna pokazuje względny czas, przy czym najszybsza funkcja ma indeks bazowy wynoszący 1.0.
for j in spec.columns:
d = pd.concat([df]* j, ignore_index=True)for i in spec.index:
stmt ='{}(d)'.format(i)
setp ='from __main__ import d, {}'.format(i)
spec.at[i, j]= timeit(stmt, setp, number=50)
Fantastyczna odpowiedź! 2 pytania, i) jak by to .iloc(numpy.where(..))porównać w tym schemacie? ii) czy spodziewałbyś się, że rankingi będą takie same, jeśli zastosujesz wiele warunków?
posdef
3
Do wykonania pd.Series.isin, trzeba pamiętać, że nie stosowanie np.in1dpod maską w konkretnym scenariuszu, Khash zastosowania w innych, a pośrednio stosuje kompromis między kosztem mieszaja kontra wydajności w konkretnych sytuacjach. Ta odpowiedź ma więcej szczegółów.
jpp
1
Przy 9 screenach jest to przeciążenie dla nowego lub nawet pośredniego użytkownika. Możesz i powinieneś sam podsumować tl; dr w pierwszym akapicie.
smci
@piRSquared Skalowanie ważne byś nic przeciwko @piRSquared, aby również zamieścić swoje doświadczenia na temat tego, jak dobrze rzeczywistych[{P|EXP}TIME] - a [{C|P|EXP}SPACE]- koszty korzystania z wyżej proponowanych form blokowo składni (top-down przetwarzanie całych dataframes naraz) rosną , a mianowicie, gdy skalowane do niektórych ~1E6, ~1E9, ~1E12liczb wierszy? Dzięki za pokazanie nam całego zdjęcia, Sir. Ilościowe odczyty wzorcowe z [min, Avg, MAX, StDev]są zawsze mile widziane, ponieważ zarówno wartości , jak mini MAXwartości towarzyszą Mean/StDevzwolnieniu partii.
import pandas as pd
# Create data set
d ={'foo':[100,111,222],'bar':[333,444,555]}
df = pd.DataFrame(d)# Full dataframe:
df
# Shows:# bar foo # 0 333 100# 1 444 111# 2 555 222# Output only the row(s) in df where foo is 222:
df[df.foo ==222]# Shows:# bar foo# 2 555 222
W powyższym kodzie jest to wiersz, df[df.foo == 222]który podaje wiersze na podstawie wartości kolumny, 222w tym przypadku.
queryto jedyna odpowiedź tutaj zgodna z łańcuchem metod. Wygląda na to, że to pandy analogiczne do filterdplyr.
Berk U.
3
Cześć, w trzecim przykładzie (wiele kolumn) Myślę, że potrzebujesz nawiasów kwadratowych, a [nie okrągłych (na zewnątrz.
user2739472
2
na początku myślałem, że |to dla AND, ale oczywiście jest to operator OR ...
O-9
dla wielu warunków przy użyciu AND, można to zrobićdf[condition1][condition2]
Ritwik
1
Pozostawiając to tutaj na wypadek, gdy jest to przydatne dla kogoś: z kwerendy 0.25 można używać nazw kolumn zawierających spacje w nazwie, umieszczając ją w backticksach:df.query('`my col` == 124')
cs95
65
Uważam, że składnia poprzednich odpowiedzi jest zbędna i trudna do zapamiętania. Pandas wprowadził tę query()metodę w wersji 0.13 i zdecydowanie wolę ją. Na twoje pytanie możesz to zrobićdf.query('col == val')
In[167]: n =10In[168]: df = pd.DataFrame(np.random.rand(n,3), columns=list('abc'))In[169]: df
Out[169]:
a b c
00.6877040.5823140.28164510.2508460.6100210.42012120.6243280.4018160.93214630.0117630.0229210.24418640.5901980.3256800.89039250.5988920.2964240.00731260.6346250.8030690.12387270.9241680.3250760.30374680.1168220.3645640.45460790.9861420.7519530.561512# pure pythonIn[170]: df[(df.a < df.b)&(df.b < df.c)]Out[170]:
a b c
30.0117630.0229210.24418680.1168220.3645640.454607# queryIn[171]: df.query('(a < b) & (b < c)')Out[171]:
a b c
30.0117630.0229210.24418680.1168220.3645640.454607
Możesz również uzyskać dostęp do zmiennych w środowisku, przygotowując plik @.
exclude =('red','orange')
df.query('color not in @exclude')
Potrzebujesz tylko numexprzainstalowanego pakietu .
MERose
4
W moim przypadku potrzebowałem cytatu, ponieważ val jest łańcuchem. df.query ('col == "val"')
smerlung
28
Większa elastyczność .querydzięki pandas >= 0.25.0:
Zaktualizowana odpowiedź z sierpnia 2019 r
Ponieważ pandas >= 0.25.0możemy użyć tej querymetody do filtrowania ramek danych za pomocą metod pand, a nawet nazw kolumn zawierających spacje. Normalnie spacje w nazwach kolumn dawałyby błąd, ale teraz możemy to rozwiązać za pomocą backsticka (`) patrz GitHub :
In[76]: df.iloc[np.where(df.A.values=='foo')]Out[76]:
A B C D
0 foo one 002 foo two 244 foo two 486 foo one 6127 foo three 714
Porównanie czasowe:
In[68]:%timeit df.iloc[np.where(df.A.values=='foo')]# fastest1000 loops, best of 3:380µs per loop
In[69]:%timeit df.loc[df['A']=='foo']1000 loops, best of 3:745µs per loop
In[71]:%timeit df.loc[df['A'].isin(['foo'])]1000 loops, best of 3:562µs per loop
In[72]:%timeit df[df.A=='foo']1000 loops, best of 3:796µs per loop
In[74]:%timeit df.query('(A=="foo")')# slowest1000 loops, best of 3:1.71 ms per loop
from pandas importDataFrame# Create data set
d ={'Revenue':[100,111,222],'Cost':[333,444,555]}
df =DataFrame(d)# mask = Return True when the value in column "Revenue" is equal to 111
mask = df['Revenue']==111print mask
# Result:# 0 False# 1 True# 2 False# Name: Revenue, dtype: bool# Select * FROM df WHERE Revenue = 111
df[mask]# Result:# Cost Revenue# 1 444 111
Aby dołączyć do tego znanego pytania (choć trochę za późno): Możesz także zrobić df.groupby('column_name').get_group('column_desired_value').reset_index()nową ramkę danych z określoną kolumną o określonej wartości. Na przykład
import pandas as pd
df = pd.DataFrame({'A':'foo bar foo bar foo bar foo foo'.split(),'B':'one one two three two two one three'.split()})print("Original dataframe:")print(df)
b_is_two_dataframe = pd.DataFrame(df.groupby('B').get_group('two').reset_index()).drop('index', axis =1)#NOTE: the final drop is to remove the extra index column returned by groupby objectprint('Sub dataframe where B is two:')print(b_is_two_dataframe)
Uruchom to daje:
Original dataframe:
A B
0 foo one
1 bar one
2 foo two
3 bar three
4 foo two
5 bar two
6 foo one
7 foo three
Sub dataframe where B is two:
A B
0 foo two
1 foo two
2 bar two
Świetna odpowiedź. Chciałbym tylko dodać, że drugi (pd.DataFrame) jest zbędny, ponieważ get_group()automatycznie zwróci ramkę danych. Możesz także powiedzieć „drop = True” jako parametr parametru reset_index(). Innymi słowy, można go skrócić do: b_is_two_dataframe = df.groupby('B').get_group('two').reset_index(drop=True)
Odpowiedzi:
Aby wybrać wiersze, których wartość kolumny jest równa skalarowi
some_value
, użyj==
:Aby wybrać wiersze, których wartość kolumny jest iterowalna
some_values
, użyjisin
:Połącz wiele warunków z
&
:Zwróć uwagę na nawiasy. Ze względu na reguły pierwszeństwa operatora Pythona ,
&
wiązania są ściślejsze niż<=
i>=
. Dlatego nawiasy w ostatnim przykładzie są konieczne. Bez nawiasówjest analizowany jako
co powoduje, że wartość Prawdy Serii jest niejednoznacznym błędem .
Aby wybrać wiersze, których wartość kolumny nie jest równa
some_value
, użyj!=
:isin
Zwraca wartość logiczną z serii, tak aby wybrać wiersze, których wartość jest nie wsome_values
, neguje logiczną Series przy użyciu~
:Na przykład,
daje
Jeśli masz wiele wartości, które chcesz uwzględnić, umieść je na liście (lub bardziej ogólnie, dowolne iterowalne) i użyj
isin
:daje
Pamiętaj jednak, że jeśli chcesz to zrobić wiele razy, bardziej efektywne jest najpierw utworzenie indeksu, a następnie użycie
df.loc
:daje
lub, aby dołączyć wiele wartości z indeksu, użyj
df.index.isin
:daje
źródło
df.where(condition)
warunek musi mieć taki sam kształt jakdf
.df[df['column_name'] == some_value]
działa, dlaczego potrzebujemy.loc
tutaj dodać ?Istnieje kilka sposobów wybierania wierszy z ramki danych pand:
df[df['col'] == value
])df.iloc[...]
)df.xs(...)
)df.query(...)
APIPoniżej pokazuję przykłady każdego z nich wraz z radą, kiedy stosować określone techniki. Załóżmy, że naszym kryterium jest kolumna
'A'
=='foo'
(Uwaga na temat wydajności: w przypadku każdego typu podstawowego możemy uprościć sprawę, używając interfejsu API pand lub możemy wyjść poza interfejs API, zwykle w celu
numpy
przyspieszenia.)Konfiguracja
Pierwszą rzeczą, której potrzebujemy, jest określenie warunku, który będzie naszym kryterium wyboru wierszy. Zaczniemy od przypadku OP
column_name == some_value
i dołączymy kilka innych typowych przypadków użycia.Pożyczanie od @unutbu:
1. Indeksowanie boolowskie
... Indeksowanie boolowskie wymaga znalezienia prawdziwej wartości
'A'
kolumny każdego wiersza równej'foo'
, a następnie użycia tych wartości prawdy do zidentyfikowania, które wiersze zachować. Zazwyczaj chcielibyśmy nazwać tej serii tablicę wartości prawdęmask
. Zrobimy to również tutaj.Następnie możemy użyć tej maski do wycinania lub indeksowania ramki danych
Jest to jeden z najprostszych sposobów wykonania tego zadania, a jeśli wydajność lub intuicyjność nie stanowią problemu, powinna to być wybrana metoda. Jeśli jednak wydajność stanowi problem, warto rozważyć alternatywny sposób utworzenia pliku
mask
.2. Indeksowanie pozycji
Indeksowanie pozycyjne (
df.iloc[...]
) ma swoje przypadki użycia, ale nie jest to jeden z nich. Aby określić, gdzie należy kroić, najpierw musimy wykonać tę samą analizę boolowską, którą wykonaliśmy powyżej. To pozostawia nam jeden dodatkowy krok do wykonania tego samego zadania.3. Indeksowanie etykiet
Indeksowanie etykiet może być bardzo przydatne, ale w tym przypadku ponownie wykonujemy więcej pracy bez żadnych korzyści
4.
df.query()
APIpd.DataFrame.query
jest bardzo eleganckim / intuicyjnym sposobem wykonania tego zadania, ale często jest wolniejszy. Jednakże , jeśli zwrócić uwagę na czasy poniżej, dla dużych danych, zapytanie jest bardzo wydajny. Bardziej niż standardowe podejście i podobnej wielkości jak moja najlepsza sugestia.Preferuję używanie
Boolean
mask
Rzeczywistych ulepszeń można dokonać, modyfikując sposób, w jaki tworzymy nasze
Boolean
mask
.mask
alternatywa 1Użyj podstawowej
numpy
tablicy i zrezygnuj z narzutów związanych z tworzeniem kolejnejpd.Series
Na końcu pokażę pełniejsze testy czasowe, ale spójrzmy tylko na wzrost wydajności, jaki uzyskujemy dzięki przykładowej ramce danych. Najpierw przyjrzymy się różnicy w tworzeniu
mask
Ocena za
mask
pomocąnumpy
tablicy jest ~ 30 razy szybsza. Wynika to częściowo z tego, żenumpy
ocena jest często szybsza. Wynika to również częściowo z braku narzutu niezbędnego do zbudowania indeksu i odpowiedniegopd.Series
obiektu.Następnie przyjrzymy się terminowi krojenia z jednym
mask
na drugi.Wzrost wydajności nie jest tak wyraźny. Zobaczymy, czy to wytrzyma bardziej szczegółowe testy.
mask
alternatywa 2Mogliśmy również zrekonstruować ramkę danych. Podczas odtwarzania ramki danych istnieje duże zastrzeżenie - musisz się tym zająć
dtypes
to zrobić!Zamiast tego
df[mask]
to zrobimyJeśli ramka danych jest typu mieszanego, jak w naszym przykładzie, to kiedy otrzymamy
df.values
wynikową tablicę, będzie onadtype
object
zawierała wszystkie kolumny nowej ramki danychdtype
object
. Wymaga toastype(df.dtypes)
i zabija wszelkie potencjalne przyrosty wydajności.Jeśli jednak ramka danych nie jest typu mieszanego, jest to bardzo przydatny sposób na zrobienie tego.
Dany
Przeciw
Skróciliśmy czas o połowę.
mask
alternatywa 3@unutbu pokazuje również, jak używać
pd.Series.isin
do rozliczania każdego elementudf['A']
znajdującego się w zbiorze wartości. To ocenia to samo, jeśli nasz zestaw wartości jest zbiorem jednej wartości, a mianowicie'foo'
. Ale uogólnia również, aby w razie potrzeby uwzględnić większe zestawy wartości. Okazuje się, że wciąż jest to dość szybkie, mimo że jest to bardziej ogólne rozwiązanie. Jedyną prawdziwą stratą jest intuicyjność dla tych, którzy nie znają tej koncepcji.Jednak, jak poprzednio, możemy wykorzystać
numpy
do poprawy wydajności, poświęcając praktycznie nic. Użyjemynp.in1d
Czas
uwzględnię również inne pojęcia wymienione w innych postach w celach informacyjnych.
Kod poniżej
Każda kolumna w tej tabeli reprezentuje ramkę danych o innej długości, w której testujemy każdą funkcję. Każda kolumna pokazuje względny czas, przy czym najszybsza funkcja ma indeks bazowy wynoszący
1.0
.Zauważysz, że najszybsze czasy wydają się być dzielone między
mask_with_values
imask_with_in1d
Funkcje
Testowanie
Specjalny czas
Patrząc na szczególny przypadek, gdy mamy pojedynczy obiekt niebędący obiektem
dtype
dla całej ramki danych. Kod poniżejOkazuje się, że odbudowa nie jest warta kilkuset rzędów.
Funkcje
Testowanie
źródło
.iloc(numpy.where(..))
porównać w tym schemacie? ii) czy spodziewałbyś się, że rankingi będą takie same, jeśli zastosujesz wiele warunków?pd.Series.isin
, trzeba pamiętać, że nie stosowanienp.in1d
pod maską w konkretnym scenariuszu, Khash zastosowania w innych, a pośrednio stosuje kompromis między kosztem mieszaja kontra wydajności w konkretnych sytuacjach. Ta odpowiedź ma więcej szczegółów.[{P|EXP}TIME]
- a[{C|P|EXP}SPACE]
- koszty korzystania z wyżej proponowanych form blokowo składni (top-down przetwarzanie całych dataframes naraz) rosną , a mianowicie, gdy skalowane do niektórych~1E6, ~1E9, ~1E12
liczb wierszy? Dzięki za pokazanie nam całego zdjęcia, Sir. Ilościowe odczyty wzorcowe z[min, Avg, MAX, StDev]
są zawsze mile widziane, ponieważ zarówno wartości , jakmin
iMAX
wartości towarzysząMean/StDev
zwolnieniu partii.tl; dr
Pandy równoważne
jest
Wiele warunków:
lub
Przykład kodu
W powyższym kodzie jest to wiersz,
df[df.foo == 222]
który podaje wiersze na podstawie wartości kolumny,222
w tym przypadku.Możliwe są również różne warunki:
Ale w tym momencie zaleciłbym użycie funkcji zapytania , ponieważ jest mniej gadatliwa i daje ten sam wynik:
źródło
query
to jedyna odpowiedź tutaj zgodna z łańcuchem metod. Wygląda na to, że to pandy analogiczne dofilter
dplyr.[
nie okrągłych(
na zewnątrz.|
to dla AND, ale oczywiście jest to operator OR ...df[condition1][condition2]
df.query('`my col` == 124')
Uważam, że składnia poprzednich odpowiedzi jest zbędna i trudna do zapamiętania. Pandas wprowadził tę
query()
metodę w wersji 0.13 i zdecydowanie wolę ją. Na twoje pytanie możesz to zrobićdf.query('col == val')
Reprodukcja z http://pandas.pydata.org/pandas-docs/version/0.17.0/indexing.html#indexing-query
Możesz również uzyskać dostęp do zmiennych w środowisku, przygotowując plik
@
.źródło
numexpr
zainstalowanego pakietu .Większa elastyczność
.query
dziękipandas >= 0.25.0
:Zaktualizowana odpowiedź z sierpnia 2019 r
Ponieważ
pandas >= 0.25.0
możemy użyć tejquery
metody do filtrowania ramek danych za pomocą metod pand, a nawet nazw kolumn zawierających spacje. Normalnie spacje w nazwach kolumn dawałyby błąd, ale teraz możemy to rozwiązać za pomocą backsticka (`) patrz GitHub :Za
.query
pomocą metodystr.endswith
:Wynik
Możemy również użyć zmiennych lokalnych, poprzedzając je
@
w naszym zapytaniu:Wynik
źródło
Szybsze wyniki można osiągnąć za pomocą numpy.where .
Na przykład przy konfiguracji unubtu -
Porównanie czasowe:
źródło
Oto prosty przykład
źródło
Aby wybrać tylko określone kolumny z wielu kolumn dla danej wartości w pandach:
Opcje:
lub
źródło
Aby dołączyć do tego znanego pytania (choć trochę za późno): Możesz także zrobić
df.groupby('column_name').get_group('column_desired_value').reset_index()
nową ramkę danych z określoną kolumną o określonej wartości. Na przykładUruchom to daje:
źródło
get_group()
automatycznie zwróci ramkę danych. Możesz także powiedzieć „drop = True” jako parametr parametrureset_index()
. Innymi słowy, można go skrócić do:b_is_two_dataframe = df.groupby('B').get_group('two').reset_index(drop=True)
Możesz także użyć .apply:
W rzeczywistości działa wierszowo (tzn. Stosuje funkcję do każdego wiersza).
Dane wyjściowe to
Wyniki są takie same jak przy użyciu, jak wspomniano w @unutbu
źródło