14
votes

Solution pour SpecificationError: le renommage imbriqué n'est pas pris en charge tandis que agg () avec groupby ()

SpecificationError                        Traceback (most recent call last)
<ipython-input-21-2cace8f16608> in <module>()
----> 1 univariate_barplots(project_data, 'school_state', 'project_is_approved', False)

<ipython-input-20-856fcc83737b> in univariate_barplots(data, col1, col2, top)
      4 
      5     # Pandas dataframe grouby count: https://stackoverflow.com/a/19385591/4084039
----> 6     temp['total'] = pd.DataFrame(project_data.groupby(col1)[col2].agg({'total':'count'})).reset_index()['total']
      7     print (temp['total'].head(2))
      8     temp['Avg'] = pd.DataFrame(project_data.groupby(col1)[col2].agg({'Avg':'mean'})).reset_index()['Avg']

~\AppData\Roaming\Python\Python36\site-packages\pandas\core\groupby\generic.py in aggregate(self, func, *args, **kwargs)
    251             # but not the class list / tuple itself.
    252             func = _maybe_mangle_lambdas(func)
--> 253             ret = self._aggregate_multiple_funcs(func)
    254             if relabeling:
    255                 ret.columns = columns

~\AppData\Roaming\Python\Python36\site-packages\pandas\core\groupby\generic.py in _aggregate_multiple_funcs(self, arg)
    292             # GH 15931
    293             if isinstance(self._selected_obj, Series):
--> 294                 raise SpecificationError("nested renamer is not supported")
    295 
    296             columns = list(arg.keys())

SpecificationError: **nested renamer is not supported**

2 commentaires

Autant les réponses de code uniquement sont déconseillées sur StackOverflow, tout comme les publications de code uniquement. Veuillez expliquer quelque chose de ce processus.


Vous pouvez également obtenir cette erreur si vous essayez d'agréger et qu'une ou plusieurs colonnes ne sont pas présentes dans le bloc de données


10 Réponses :


3
votes

Obtenez-vous la même erreur si vous changez

temp['total'] = project_data.groupby(col1)[col2].agg(total=('total','count')).reset_index()['total']

à

temp['total'] = pd.DataFrame(project_data.groupby(col1)[col2].agg({'total':'count'})).reset_index()['total']


0 commentaires

28
votes

changement

temp['total'] = pd.DataFrame(project_data.groupby(col1)[col2].agg(total='count')).reset_index()['total']
temp['Avg'] = pd.DataFrame(project_data.groupby(col1)[col2].agg(Avg='mean')).reset_index()['Avg']

à

temp['total'] = pd.DataFrame(project_data.groupby(col1)[col2].agg({'total':'count'})).reset_index()['total']

temp['Avg'] = pd.DataFrame(project_data.groupby(col1)[col2].agg({'Avg':'mean'})).reset_index()['Avg']

raison: dans la nouvelle version de pandas, l'agrégation nommée est le remplacement recommandé pour l'approche obsolète «dict-of-dicts» pour nommer la sortie des agrégations spécifiques aux colonnes (observez groupby.agg () avec un dictionnaire lors du changement de nom).

source: https://pandas.pydata.org/pandas-docs/stable/whatsnew/v0.25.0.html


0 commentaires

34
votes

Cette erreur se produit également si une colonne spécifiée dans la fonction d'agrégation dict n'existe pas dans le dataframe:

In [190]: group = pd.DataFrame([[1, 2]], columns=['A', 'B']).groupby('A')
In [195]: group.agg({'B': 'mean'})
Out[195]: 
   B
A   
1  2

In [196]: group.agg({'B': 'mean', 'non-existing-column': 'mean'})
...
SpecificationError: nested renamer is not supported


1 commentaires

Cette réponse indique la source réelle de l'erreur. L'autre réponse indiquant qu'il existe une autre façon de spécifier peut être vraie mais n'atteint pas la cause première.



0
votes

J'ai le même problème que @akshay jindal, mais je vérifie la documentation comme suggéré par @artikay Khanna, le problème est résolu, certaines fonctions ont été ajustées, l'ancienne est obsolète. Voici l'avertissement de code fourni lors de la dernière exécution.

grouper.agg(name_1=func_1, name_2=func_2)

Par conséquent, je suggérerai d'essayer

/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:1: FutureWarning: using a dict on a Series for aggregation
is deprecated and will be removed in a future version. Use                 named aggregation instead.

    >>> grouper.agg(name_1=func_1, name_2=func_2)

  """Entry point for launching an IPython kernel.

J'espère que cela aidera


0 commentaires

0
votes

J'ai essayé toutes les solutions et s'est avéré être l'erreur avec le nom. Si le nom de votre colonne a des mots-clés intégrés tels que "in", "is", etc., cela génère une erreur. Dans mon cas, le nom de ma colonne est "Points dans le polygone" et j'ai résolu le problème en renommant la colonne en "Points"


0 commentaires

0
votes

La solution de @ Rishi a fonctionné pour moi. Le nom d'origine de la colonne dans mon dataframe était net_value_budgeted_rate , qui était essentiellement la valeur en dollars de la vente. Je l'ai changé en dollars et cela a fonctionné.


0 commentaires

0
votes

Au lieu d'utiliser .agg({'total':'count'})) , vous pouvez passer le nom avec la fonction comme une liste de tuple comme .agg([('total', 'count')]) et utiliser le même pour Avg aussi. J'espère que cela fonctionnerait.


1 commentaires

Cette solution a l'avantage de nommer correctement les colonnes résultantes.



1
votes

Pas une solution très élégante mais celle-ci fonctionne. Comme renommer la colonne est obsolète avec la façon dont vous faites. Mais il y a du travail autour. Créez une variable temporaire « approuvée », stockez-y le col2 . Parce que lorsque vous appliquez la fonction agg, les valeurs de colonne d'origine changeront avec le nom de la colonne. Vous pouvez conserver le nom de la colonne, mais les valeurs de ces colonnes changeront. Ainsi, afin de conserver le dataframe d'origine et d'avoir deux nouvelles colonnes avec les noms souhaités, vous pouvez utiliser le code suivant.

approved = temp[col2]
temp = pd.DataFrame(project_data.groupby(col1)[col2].agg([('Avg','mean'),('total','count')]).reset_index())
temp[col2] = approved

PS: On dirait une mission d'AAIC, je travaille sur le même :)


0 commentaires

0
votes

Parfois, il est pratique de garder un aggdict de la façon dont chaque colonne doit être transformée sous agrégation qui fonctionnera avec différents ensembles de colonnes et différents groupes par colonnes. Vous pouvez le faire avec la nouvelle syntaxe assez facilement en décompressant le dict avec **. Voici un exemple de travail minimal pour des données simples.

mygb = lambda gb_col: dfx.groupby(gb_col).agg(**{k:(k,v) for k,v in aggdict.items() if k in dfx.columns and k != gb_col})
allgb = [mygb(c) for c in dfx.columns]

Peut-être que lorsque vous agissez, vous voulez le premier "A" , le dernier "B" , le "C" et parfois votre pipeline a un "D" (mais pas cette fois) dont vous voulez aussi la moyenne.

gb_col="C"
gbc = dfx.groupby(gb_col).agg(**{k:(k,v) for k,v in aggdict.items() if k in dfx.columns and k != gb_col})
#       A  B
#C      
#1  4  2
#2  0  0
#3  1  4
#4  2  3

Vous pouvez créer un dict simple comme autrefois, puis le décompresser avec ** filtrage sur les clés pertinentes:

aggdict = {"A":lambda x: x.iloc[0], "B": lambda x: x.iloc[-1], "C" : "mean" , "D":lambda x: "mean"}

Et puis vous pouvez trancher et couper en dés comme vous le souhaitez avec la même syntaxe:

dfx=pd.DataFrame(columns=["A","B","C"],data=np.random.randint(0,5,size=(10,3)))
#dfx
#
#   A  B  C
#0  4  4  1
#1  2  4  4
#2  1  3  3
#3  2  4  3
#4  1  2  1
#5  0  4  2
#6  2  3  4
#7  1  0  2
#8  2  1  4
#9  3  0  3


0 commentaires

0
votes

J'ai trouvé le chemin: au lieu d'aller comme

g2 = df.groupby(["Description","CustomerID"],as_index=False).agg({'Quantity':{np.max,np.min,np.mean}})
g2.columns = ["Description","CustomerID","maxQ","minQ",'meanQ']

Procédez comme suit:

g2 = df.groupby(["Description","CustomerID"],as_index=False).agg({'Quantity':{"maxQ":np.max,"minQ":np.min,"meanQ":np.mean}})
g2.columns = ["Description","CustomerID","maxQ","minQ",'meanQ']

J'ai eu la même erreur et c'est ainsi que je l'ai résolue!


0 commentaires