2017-07-27 1 views
3

Je regardais la méthode pandas DataFrame eval (docs) que je trouve un bon sucre syntaxique et pourrait également aider enhancing performances.Pandas DataFrame eval avec l'espace dans les noms de colonnes

C'est l'exemple de la documentation:

from numpy.random import randn 
import pandas as pd 

df = pd.DataFrame(randn(10, 2), columns=list('ab')) 
df.eval('a + b') 

Comment puis-je utiliser eval quand il y a un espace dans mes noms de colonnes? Exemple:

df = pd.DataFrame(randn(10, 2), columns=["Col 1", "Col 2"]) 

J'ai essayé ceci:

df.eval('"Col 1" + "Col 2"') 

mais cela donne l'erreur:

TypeError: data type "Col 1" not understood 
+1

Comme il ne s'agit pas d'une méthode intégrée, * DataFrame * doit être qualifié selon les règles de Python. Vous pourriez avoir voulu dire 'pd.DateFrame' ou' de pandas importer DataFrame'? – Parfait

Répondre

2

Vous pouvez le faire en utilisant:

df.eval(df["Col 1"] + df["Col 2"]) 

Mais c'est bon d'aller contre t Le but de la fonction eval.

Vous pouvez renommer vos colonnes afin de les rendre compatibles avec la syntaxe eval:

df.columns = df.columns.map(lambda x: x.replace(' ', '_')) 
+0

Oui, convenu que c'est contre le but de la fonction eval :) – FLab

+0

++ pour renommer les colonnes – MaxU

+0

Je viens de le tester ... 'df.query (" Col_1 + Col_2 ")' après avoir renommé les colonnes me donne 'KeyError'. 'pd.eval (" df.Col_1 + df.Col_2 ")' fonctionne, mais ce n'est pas très pratique par rapport à 'DataFrame.eval()' IMO ... – MaxU

1
pd.eval('df["Col 1"] + df["Col 2"]') 

Cela permet de maintenir l'argument eval comme une chaîne, mais est moins propre que l'exemple sans espaces dans les noms de colonnes

exemple:

print(df) 

     Col 1  Col 2 
0 -0.206838 -1.007173 
1 -0.762453 1.178220 
2 -0.431943 -0.804775 
3 0.830659 -0.244472 
4 0.111637 0.943254 
5 0.206615 0.436250 
6 -0.568307 -0.680140 
7 -0.127645 -0.098351 
8 0.185413 -1.224999 
9 0.767931 1.512654 

print(pd.eval('df["Col 1"] + df["Col 2"]')) 

0 -1.214011 
1 0.415768 
2 -1.236718 
3 0.586188 
4 1.054891 
5 0.642865 
6 -1.248447 
7 -0.225995 
8 -1.039586 
9 2.280585 
dtype: float64 

EDIT

Après enquête, il semble que la méthode ci-dessus fonctionne soit dans Python 2.7 ou 3.6 si vous utilisez le moteur python:

pd.eval('df["Col 1"] + df["Col 2"]', engine='python') 

Cependant, cela ne vous donne pas l'avantage de performance le moteur numexpr peut fournir. En Python 2.7, cette méthode fonctionne:

pd.eval('df["Col 1"] + df["Col 2"]', engine='numexpr') 

mais en python 3.6 vous obtenez l'erreur ValueError: unknown type str160.

Je suppose que c'est parce que pandas passe une chaîne unicode à numexpr dans 3.6 mais un bytestring dans 2.7. Je devine que ce problème est lié à this issue et peut-être this one ainsi.

+0

l'avez-vous testé? Cela me donne 'ValueError: type inconnu str160' (Pandas 0.20.1). Quelle est votre version de Pandas? – MaxU

+0

@MaxU, je crois ... (voir l'exemple). Y a-t-il d'autres tests que vous recommanderiez? – bunji

+0

Pourriez-vous préciser votre version de Pandas? Je voudrais le tester moi-même ... – MaxU