Salut, je suis nouveau à Pandas et je viens de rencontrer df.query()
.
Pourquoi les gens utiliseraient df.query()
quand vous pouvez filtrer directement vos Dataframes en utilisant la notation des crochets? Le tutoriel officiel pandas semble également préférer cette dernière approche.
Avec la notation entre parenthèses:
df[df['age'] <= 21]
Avec pandas méthode de requête:
df.query('age <= 21')
Outre certaines des différences stylistiques ou de flexibilité qui ont été mentionnées, est-ce une préférence canonique - à savoir pour l'exécution d'opérations sur de grandes trames de données?
Considérez l'exemple DF suivant:
In [307]: df
Out[307]:
sex age name
0 M 40 Max
1 F 35 Anna
2 M 29 Joe
3 F 18 Maria
4 F 23 Natalie
Il y a plusieurs bonnes raisons de préférer la méthode .query()
.
il pourrait être beaucoup plus court et plus propre que l'indexation booléenne:
In [308]: df.query("20 <= age <= 30 and sex=='F'")
Out[308]:
sex age name
4 F 23 Natalie
In [309]: df[(df['age']>=20) & (df['age']<=30) & (df['sex']=='F')]
Out[309]:
sex age name
4 F 23 Natalie
vous pouvez préparer des conditions (requêtes) par programme:
In [315]: conditions = {'name':'Joe', 'sex':'M'}
In [316]: q = ' and '.join(['{}=="{}"'.format(k,v) for k,v in conditions.items()])
In [317]: q
Out[317]: 'name=="Joe" and sex=="M"'
In [318]: df.query(q)
Out[318]:
sex age name
2 M 29 Joe
PS il y a aussi quelques inconvénients:
.query()
pour les colonnes contenant des espaces ou des colonnes constituées uniquement de chiffresengine='python'
au lieu de la valeur par défaut engine='numexpr'
(qui est plus rapide)REMARQUE: Jeff (l'un des principaux contributeurs Pandas et membre de Pandas core team) ne fois dit :
Notez qu'en réalité .query est juste une interface agréable à avoir, en fait, il a des garanties très spécifiques, ce qui signifie qu'il est destiné à être analysé comme un langage de requête, et non une interface entièrement générale.
Quelques autres utilisations intéressantes dans le documentation .
Un cas d'utilisation pour query () est lorsque vous avez une collection d'objets DataFrame qui ont un sous-ensemble de noms de colonnes (ou de niveaux/noms d'index) en commun. Vous pouvez transmettre la même requête aux deux cadres sans avoir à spécifier quel cadre vous souhaitez interroger - (Source)
Exemple:
dfA = pd.DataFrame([[1,2,3], [4,5,6]], columns=["X", "Y", "Z"])
dfB = pd.DataFrame([[1,3,3], [4,1,6]], columns=["X", "Y", "Z"])
q = "(X > 3) & (Y < 10)"
print(dfA.query(q))
print(dfB.query(q))
X Y Z
1 4 5 6
X Y Z
1 4 1 6
df.query('a < b and b < c') # understand a bit more English
in
et not in
(alternative à isin
)df.query('a in [3, 4, 5]') # select rows whose value of column a is in [2, 3, 4]
in
/not in
)df.query('a == [1, 3, 5]') # select whose value of column a is in [1, 3, 5]
# equivalent to df.query('a in [1, 3, 5]')