Metoda query()
Zapisywać czytelne wyrażenia filtrujące jako ciągi znaków za pomocą query(), używać zmiennych Pythona wewnątrz zapytań dzięki @ oraz łączyć filtry
Metoda query() to bezpłatna lekcja Pandas & NumPy Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Pandas & NumPy Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Pandas & NumPy Academy zawiera 4 lekcji w sumie.
Dlaczego warto używać query()?
Indeksowanie logiczne w Pandas jest potężne, ale przy łączeniu wielu warunków może stać się rozwlekłe. Metoda query() pozwala zapisywać wyrażenia filtrujące jako zwykłe ciągi znaków, co wiele osób uważa za bardziej czytelne — zwłaszcza osoby mające doświadczenie z SQL. Zamiast df[(df['age'] > 30) & (df['salary'] > 50000)] można napisać df.query('age > 30 and salary > 50000').
Ciąg zapytania jest interpretowany względem nazw kolumn obiektu DataFrame, dlatego nazwy kolumn działają wewnątrz tego ciągu jak nazwy zmiennych.
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Carol', 'Dave'],
'age': [25, 35, 28, 45],
'salary': [50000, 90000, 70000, 120000]
})
# Boolean indexing style
result1 = df[(df['age'] > 27) & (df['salary'] > 60000)]
# Equivalent query() style
result2 = df.query('age > 27 and salary > 60000')
print(result2)
# name age salary
# 1 Bob 35 90000
# 2 Carol 28 70000Reguły składni wewnątrz ciągu zapytania
Wewnątrz ciągu zapytania można używać standardowych operatorów porównania języka Python (>, <, ==, !=, >=, <=) oraz operatorów logicznych and, or, not. W przeciwieństwie do zwykłego indeksowania logicznego można tutaj używać angielskich słów — nie są potrzebne operatory ampersand ani pipe.
Nazwy kolumn zawierające spacje lub kolidujące ze słowami kluczowymi Pythona należy ująć w odwrotne apostrofy: df.query('`first name` == "Alice"').
import pandas as pd
df = pd.DataFrame({
'product': ['A', 'B', 'C', 'D'],
'price': [10, 200, 50, 300],
'in_stock': [True, False, True, True]
})
# Use 'and', 'or', 'not' in query strings
result = df.query('price > 40 and in_stock == True')
print(result)
# product price in_stock
# 2 C 50 True
# 3 D 300 TrueOdwoływanie się do zmiennych Pythona za pomocą @
Ważną funkcją query() jest możliwość odwoływania się do zmiennych Pythona z otaczającego zakresu za pomocą prefiksu @. Ułatwia to parametryzowanie filtrów: należy obliczyć próg, zapisać go w zmiennej, a następnie użyć @variable_name w ciągu zapytania zamiast wpisywać wartość na stałe.
Ten wzorzec jest bardzo przydatny w funkcjach, które przyjmują argumenty filtrujące w czasie działania programu.
import pandas as pd
df = pd.DataFrame({
'city': ['NYC', 'LA', 'Chicago', 'Houston'],
'population': [8336817, 3979576, 2693976, 2320268]
})
min_pop = 3_000_000 # Python variable
# Use @ to inject the variable into the query
result = df.query('population > @min_pop')
print(result)
# city population
# 0 NYC 8336817
# 1 LA 3979576Łączenie wywołań query()
Ponieważ query() zwraca nowy obiekt DataFrame, można łączyć wiele wywołań query lub zestawiać je z innymi metodami Pandas w potoku. Łączenie umieszcza każdy krok filtrowania w osobnym wierszu, dzięki czemu logika jest łatwa do odczytania, debugowania i modyfikowania.
Można również łączyć query() z metodami takimi jak .groupby(), .sort_values() czy .head(), aby budować zwięzłe potoki analityczne.
import pandas as pd
df = pd.DataFrame({
'region': ['North', 'South', 'North', 'East', 'South'],
'year': [2022, 2022, 2023, 2023, 2023],
'revenue': [100, 200, 150, 80, 300]
})
# Chain two query calls
result = (df
.query('year == 2023')
.query('revenue > 100')
.sort_values('revenue', ascending=False)
)
print(result)
# region year revenue
# 4 South 2023 300
# 2 North 2023 150Porównanie query() z indeksowaniem logicznym
Obie metody dają ten sam wynik, ale każda z nich sprawdza się w innych sytuacjach. query() świetnie nadaje się do filtrów z wieloma warunkami, które przy indeksowaniu logicznym wymagałyby wielu nawiasów. Indeksowanie logiczne jest lepsze, gdy warunek obejmuje złożone wyrażenia Pythona, takie jak wywołania metod nieobsługiwane w ciągach zapytań.
W większości przypadków wydajność jest podobna; query() może być nieco szybsze dla bardzo dużych obiektów DataFrame, ponieważ wewnętrznie korzysta z biblioteki numexpr.
import pandas as pd
df = pd.DataFrame({
'A': range(10),
'B': range(10, 20)
})
# Boolean indexing
result_bool = df[(df['A'] > 2) & (df['B'] < 18) & (df['A'] != 5)]
# Equivalent query — much more readable
result_query = df.query('A > 2 and B < 18 and A != 5')
print(result_query)
# A B
# 3 3 13
# 4 4 14
# 6 6 16
# 7 7 17Porównywanie ciągów znaków w query()
Wartości w kolumnie tekstowej można filtrować wewnątrz ciągu zapytania, umieszczając literał tekstowy w cudzysłowie. Należy użyć podwójnych cudzysłowów dla zewnętrznego ciągu zapytania i pojedynczych cudzysłowów dla wartości tekstowej albo odwrotnie — ważne, aby zachować konsekwencję. Należy pamiętać, że query() nie obsługuje metod .str, takich jak contains(); w takim przypadku należy użyć indeksowania logicznego z .str.
import pandas as pd
df = pd.DataFrame({
'country': ['USA', 'UK', 'Canada', 'USA', 'Germany'],
'sales': [400, 150, 200, 600, 300]
})
# Single quotes for the string value inside double-quoted query
result = df.query('country == "USA"')
print(result)
# country sales
# 0 USA 400
# 3 USA 600Używanie operatorów in i not in
Wewnątrz ciągów zapytań Pandas obsługuje operatory in i not in do sprawdzania przynależności, podobnie jak w przypadku list Pythona. Jest to czytelna alternatywa dla łączenia wielu warunków == za pomocą or. Lista wartości jest zapisywana bezpośrednio w ciągu zapytania.
import pandas as pd
df = pd.DataFrame({
'status': ['active', 'inactive', 'pending', 'active', 'closed'],
'amount': [100, 200, 50, 300, 150]
})
# Keep rows where status is in a specific list
result = df.query('status in ["active", "pending"]')
print(result)
# status amount
# 0 active 100
# 2 pending 50
# 3 active 300
# Exclude certain statuses
excluded = df.query('status not in ["closed", "inactive"]')
print(excluded.shape) # (3, 2)Filtrowanie zakresów liczbowych za pomocą query()
Łańcuchowe porównania Pythona, takie jak 10 < price < 500, działają wewnątrz ciągów zapytań, dzięki czemu filtry zakresów są bardzo wyraziste. Nie jest to możliwe przy standardowym indeksowaniu logicznym bez użycia between() lub dwóch osobnych warunków połączonych operatorem &.
import pandas as pd
df = pd.DataFrame({
'product': ['A', 'B', 'C', 'D', 'E'],
'price': [5, 50, 150, 300, 500]
})
# Chained comparison — only works inside query()
result = df.query('50 <= price <= 300')
print(result)
# product price
# 1 B 50
# 2 C 150
# 3 D 300Ograniczenia query()
query() jest potężne, ale ma kilka ograniczeń. Nazwy kolumn zawierające spacje lub znaki specjalne wymagają użycia odwrotnych apostrofów. Bardzo złożone wyrażenia Pythona, takie jak funkcje niestandardowe czy logika wielowierszowa, nie są obsługiwane wewnątrz ciągu. Ponadto query() może dawać nieoczekiwane wyniki, jeśli nazwy kolumn kolidują ze słowami kluczowymi Pythona, takimi jak class czy if — je również należy ująć w odwrotne apostrofy.
W przypadku wszystkiego, czego query() nie pozwala wyrazić w czytelny sposób, należy wrócić do standardowego indeksowania logicznego.
import pandas as pd
df = pd.DataFrame({'first name': ['Alice', 'Bob'], 'class': [1, 2]})
# Backtick-quote column names with spaces or reserved words
result = df.query('`first name` == "Alice" and `class` == 1')
print(result)
# first name class
# 0 Alice 1Przykład praktyczny: filtrowanie zamówień
Oto praktyczny przykład łączący query() z odwołaniem do zmiennej oraz z łączeniem metod prowadzącym do groupby. Ten wzorzec — najpierw filtrowanie, a następnie agregowanie — pozwala uniknąć przetwarzania niepotrzebnych wierszy, dzięki czemu kod jest czytelniejszy i działa szybciej na dużych zbiorach danych.
import pandas as pd
orders = pd.DataFrame({
'region': ['East', 'West', 'East', 'West', 'East'],
'year': [2023, 2023, 2024, 2024, 2024],
'revenue': [100, 200, 300, 400, 500]
})
min_year = 2024
# Filter to recent orders in the East region, then sum revenue
summary = (
orders
.query('year >= @min_year and region == "East"')
.groupby('region')['revenue'].sum()
)
print(summary)
# region
# East 800
# Name: revenue, dtype: int64Najlepsze praktyki dotyczące query() i łączenia metod
Używanie query() w ramach łańcucha metod jest dobrą praktyką we współczesnym kodzie Pandas. Dzięki temu każdy krok potoku przekształceń jest jasny i samodokumentujący się. Cały łańcuch należy ująć w nawiasy, aby można było podzielić go na wiele wierszy bez używania ukośników odwrotnych.
Można łączyć query() z assign() w celu dodawania kolumn, groupby() w celu wykonywania agregacji oraz pipe() w celu używania funkcji niestandardowych, aby budować w pełni czytelne potoki.
import pandas as pd
df = pd.DataFrame({
'dept': ['Eng', 'HR', 'Eng', 'Sales', 'HR'],
'salary': [90000, 50000, 120000, 70000, 55000],
'years': [3, 5, 8, 2, 4]
})
result = (
df
.query('years > 2 and dept != "HR"')
.assign(bonus=lambda x: x['salary'] * 0.1)
.sort_values('salary', ascending=False)
)
print(result[['dept', 'salary', 'bonus']])
# dept salary bonus
# 2 Eng 120000 12000.0
# 0 Eng 90000 9000.0Szybki test
Sprawdź swoją wiedzę na temat metody query().
Podsumowanie lekcji
W tej lekcji poznali Państwo następujące zagadnienia: query() przyjmuje wyrażenia filtrujące jako ciągi znaków, dzięki czemu filtry z wieloma warunkami są czytelniejsze; @variable_name wstawia zmienne Pythona do zapytania; można też używać in/not in oraz porównań łańcuchowych, które nie są dostępne przy standardowym indeksowaniu logicznym. Następnie omówimy isin() i between(), służące do zwięzłego filtrowania według przynależności i zakresu.
Często zadawane pytania
Czy lekcja „Metoda query()” jest bezpłatna?
Tak — pełny tekst „Metoda query()” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Pandas & NumPy Academy, przejdź na CoddyKit PRO. Kurs Pandas & NumPy Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Metoda query()”?
Zapisywać czytelne wyrażenia filtrujące jako ciągi znaków za pomocą query(), używać zmiennych Pythona wewnątrz zapytań dzięki @ oraz łączyć filtry Ćwiczysz Pandas & NumPy Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Pandas & NumPy Academy?
Nie wymagamy żadnego doświadczenia. Pandas & NumPy Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Metoda query()”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Pandas & NumPy Academy?
Tak. Każda lekcja Pandas & NumPy Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Indeksowanie boolowskie obiektów DataFrame
- Metoda query()
- Filtry isin() i between()
- Wybieranie kolumn według wzorca