Il metodo query()
Scriva espressioni di filtro leggibili sotto forma di stringhe con query(), usi variabili Python nelle query con @ e concateni i filtri.
Il metodo query() è una lezione Pandas & NumPy Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Pandas & NumPy Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Pandas & NumPy Academy include 4 lezioni in totale.
Perché utilizzare query()?
L'indicizzazione booleana di Pandas è potente, ma può diventare prolissa quando si combinano molte condizioni. Il metodo query() consente di scrivere le espressioni di filtro come semplici stringhe, che molti trovano più leggibili, soprattutto chi proviene dal mondo SQL. Invece di df[(df['age'] > 30) & (df['salary'] > 50000)], si scrive df.query('age > 30 and salary > 50000').
La stringa della query viene valutata in base ai nomi delle colonne del DataFrame, quindi all'interno della stringa i nomi delle colonne agiscono come nomi di variabili.
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 70000Regole di sintassi all'interno di una stringa di query
All'interno di una stringa di query è possibile usare gli operatori di confronto standard di Python (>, <, ==, !=, >=, <=) e i connettori logici and, or, not. A differenza della normale indicizzazione booleana, qui è possibile usare le parole inglesi: non servono le e commerciali o le barre verticali.
I nomi delle colonne che contengono spazi o che entrano in conflitto con le parole chiave di Python devono essere racchiusi tra backtick: 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 TrueFare riferimento alle variabili Python con @
Una caratteristica importante di query() è la possibilità di fare riferimento alle variabili Python dell'ambito circostante usando il prefisso @. Questo semplifica la parametrizzazione dei filtri: si calcola una soglia, la si memorizza in una variabile e poi si usa @variable_name all'interno della stringa della query invece di inserire direttamente il valore.
Questo schema è molto utile nelle funzioni che accettano argomenti di filtro in fase di esecuzione.
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 3979576Concatenare le chiamate a query()
Poiché query() restituisce un nuovo DataFrame, è possibile concatenare più chiamate a query oppure combinarle con altri metodi Pandas in una pipeline. La concatenazione mantiene ogni passaggio di filtraggio sulla propria riga, rendendo la logica facile da leggere, eseguire il debug e modificare.
È inoltre possibile concatenare query() con metodi come .groupby(), .sort_values() o .head() per creare pipeline di analisi concise.
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 150Confronto tra query() e indicizzazione booleana
Entrambi i metodi producono lo stesso risultato, ma ciascuno è adatto a casi diversi. query() è particolarmente efficace per i filtri con più condizioni, che con l'indicizzazione booleana richiederebbero molte parentesi. L'indicizzazione booleana è preferibile quando la condizione include espressioni Python complesse, come chiamate a metodi non supportate nelle stringhe di query.
Nella maggior parte dei casi le prestazioni sono simili; query() può essere leggermente più veloce con DataFrame molto grandi perché utilizza internamente la libreria 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 17Confronti tra stringhe in query()
È possibile filtrare i valori delle colonne di tipo stringa all'interno di una stringa di query racchiudendo tra virgolette il valore letterale. Usi le virgolette doppie per la stringa esterna della query e quelle singole per il valore stringa, oppure viceversa: l'importante è essere coerenti. Tenga presente che query() non supporta metodi .str come contains(); per questi casi, usi l'indicizzazione booleana con .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 600Usare gli operatori in e not in
All'interno delle stringhe di query, Pandas supporta gli operatori in e not in per verificare l'appartenenza, in modo simile alle liste Python. Questa è un'alternativa chiara alla concatenazione di più condizioni == con or. L'elenco dei valori viene scritto direttamente nella stringa della query.
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)Filtri per intervalli numerici con query()
I confronti concatenati di Python, come 10 < price < 500, funzionano all'interno delle stringhe di query e rendono i filtri per intervallo molto espressivi. Con la normale indicizzazione booleana ciò non è possibile senza usare between() oppure due condizioni separate unite con &.
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 300Limiti di query()
query() è potente, ma presenta alcuni limiti. I nomi delle colonne con spazi o caratteri speciali devono essere racchiusi tra backtick. Le espressioni Python molto complesse, come le funzioni personalizzate o la logica su più righe, non sono supportate all'interno della stringa. Inoltre, query() può produrre risultati inattesi se i nomi delle colonne entrano in conflitto con parole chiave Python come class o if: racchiuda tra backtick anche questi nomi.
Per tutto ciò che query() non consente di esprimere in modo chiaro, torni all'indicizzazione booleana standard.
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 1Esempio pratico: filtrare gli ordini
Ecco una dimostrazione pratica che combina query() con un riferimento a una variabile e una concatenazione fino a un groupby. Questo schema, che consiste nel filtrare prima e aggregare poi, evita di elaborare righe non necessarie ed è quindi più chiaro e veloce sui dataset di grandi dimensioni.
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: int64query() e buone pratiche per la concatenazione dei metodi
Usare query() all'interno di una concatenazione di metodi è una buona pratica nel moderno codice Pandas. Rende chiaro e autoesplicativo ogni passaggio della pipeline di trasformazione. Racchiuda l'intera concatenazione tra parentesi, così potrà suddividerla su più righe senza usare barre rovesciate.
Combini query() con assign() per aggiungere colonne, groupby() per le aggregazioni e pipe() per le funzioni personalizzate, così da creare pipeline completamente leggibili.
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.0Verifica rapida
Verifichi la Sua comprensione del metodo query().
Riepilogo della lezione
In questa lezione ha imparato che: query() accetta espressioni di filtro come stringhe, rendendo più leggibili i filtri con più condizioni; @variable_name inserisce variabili Python nella query; inoltre, è possibile usare in/not in e confronti concatenati, non disponibili con la normale indicizzazione booleana. Nel prossimo argomento esploreremo isin() e between() per creare filtri concisi di appartenenza e di intervallo.
Impara Python con un tutor IA — gratis
Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.
- Corsi
- 30
- Lezioni
- 120
Domande Frequenti
La lezione «Il metodo query()» è gratuita?
Sì — il testo completo di «Il metodo query()» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Pandas & NumPy Academy, passa a CoddyKit PRO. Il corso Pandas & NumPy Academy include 4 lezioni in totale.
Cosa imparerò in «Il metodo query()»?
Scriva espressioni di filtro leggibili sotto forma di stringhe con query(), usi variabili Python nelle query con @ e concateni i filtri. Eserciti Pandas & NumPy Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Pandas & NumPy Academy?
Non è richiesta alcuna esperienza precedente. Pandas & NumPy Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «Il metodo query()»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Pandas & NumPy Academy?
Sì. Ogni lezione Pandas & NumPy Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Indicizzazione booleana dei DataFrame
- Il metodo query()
- Filtri isin() e between()
- Selezionare colonne in base a un pattern