Jak mogę uzyskać odpowiedniki SQL IN
i NOT IN
?
Mam listę z wymaganymi wartościami. Oto scenariusz:
df = pd.DataFrame({'countries':['US','UK','Germany','China']})
countries = ['UK','China']
# pseudo-code:
df[df['countries'] not in countries]
Mój obecny sposób na zrobienie tego jest następujący:
df = pd.DataFrame({'countries':['US','UK','Germany','China']})
countries = pd.DataFrame({'countries':['UK','China'], 'matched':True})
# IN
df.merge(countries,how='inner',on='countries')
# NOT IN
not_in = df.merge(countries,how='left',on='countries')
not_in = not_in[pd.isnull(not_in['matched'])]
Ale to wygląda na okropną kludge. Czy ktoś może to poprawić?
python
pandas
dataframe
sql-function
LondonRob
źródło
źródło
Odpowiedzi:
Możesz użyć
pd.Series.isin
.Do „IN” użyj:
something.isin(somewhere)
Lub dla „NOT IN”:
~something.isin(somewhere)
Jako działający przykład:
źródło
isin
dodano w .13.df = pd.Series({'countries':['US','UK','Germany','China']})
df
, zarówno mój, jak i jego, jestDataFrame
.countries
to lista.df[~df.countries.isin(countries)]
produkuje aDataFrame
, a nieSeries
i wydaje się działać nawet w wersji 0.11.0.dev-14a04dd.countries
zmiennej. Cóż, OP robi to i jest to dziedziczone, ale to, że coś zostało wcześniej zrobione źle, nie usprawiedliwia teraz tego źle.Alternatywne rozwiązanie wykorzystujące metodę .query () :
źródło
query
nie jest już eksperymentalny.Pandy oferują dwie metody:
Series.isin
iDataFrame.isin
dla serii i DataFrames, odpowiednio.Filtruj ramkę danych na podstawie JEDNEJ kolumny (dotyczy również serii)
Najczęstszym scenariuszem jest zastosowanie
isin
warunku do określonej kolumny w celu filtrowania wierszy w ramce danych.Series.isin
akceptuje różne typy jako dane wejściowe. Poniżej przedstawiono wszystkie ważne sposoby uzyskania tego, co chcesz:Filtruj według WIELU kolumn
Czasami warto zastosować kontrolę członkostwa „w” z kilkoma wyszukiwanymi hasłami w wielu kolumnach,
Aby zastosować
isin
warunek do obu kolumn „A” i „B”, użyjDataFrame.isin
:Z tego, aby zachować wiersze, w których znajduje się co najmniej jedna kolumna
True
, możemy użyćany
wzdłuż pierwszej osi:Pamiętaj, że jeśli chcesz przeszukać każdą kolumnę, po prostu pomiń krok wyboru kolumny i zrób to
Podobnie, aby zachować wiersze, w których znajdują się WSZYSTKIE kolumny
True
, użyj ichall
w taki sam sposób jak poprzednio.Godne uwagi jest mowa o:
numpy.isin
,query
, listowych (ciąg danych)Oprócz metod opisanych powyżej, można również użyć odpowiednik numpy:
numpy.isin
.Dlaczego warto to rozważyć? Funkcje NumPy są zwykle nieco szybsze niż ich odpowiedniki pandy z powodu niższego obciążenia. Ponieważ jest to operacja elementarna, która nie zależy od wyrównania indeksu, jest bardzo niewiele sytuacji, w których ta metoda nie jest odpowiednim zamiennikiem pand
isin
.Procedury pand są zwykle iteracyjne podczas pracy z łańcuchami, ponieważ operacje na łańcuchach są trudne do wektoryzacji. Istnieje wiele dowodów sugerujących, że zrozumienie listy będzie tutaj szybsze. . Teraz uciekamy się do
in
czeku.Jednak określenie tego jest nieporęczne, więc nie używaj go, chyba że wiesz, co robisz.
Wreszcie, istnieje również
DataFrame.query
została pokryta w tej odpowiedzi . numexpr FTW!źródło
Zwykle robiłem ogólne filtrowanie według wierszy takich jak to:
źródło
Chciałem odfiltrować wiersze dfbc o identyfikatorze BUSINESS_ID, który również znajdował się w identyfikatorze BUSINESS_ID parametru dfProfilesBusIds
źródło
Zestawienie możliwych rozwiązań z odpowiedzi:
Dla w:
df[df['A'].isin([3, 6])]
Dla NOT IN:
df[-df["A"].isin([3, 6])]
df[~df["A"].isin([3, 6])]
df[df["A"].isin([3, 6]) == False]
df[np.logical_not(df["A"].isin([3, 6]))]
źródło
logical_not
jest kęsem~
operatora.zaimplementować w :
nie wdrażać jak w pozostałych krajach:
źródło