def stack_plot(data, xtick, col2='project_is_approved', col3='total'): ind = np.arange(data.shape[0]) plt.figure(figsize=(20,5)) p1 = plt.bar(ind, data[col3].values) p2 = plt.bar(ind, data[col2].values) plt.ylabel('Projects') plt.title('Number of projects aproved vs rejected') plt.xticks(ind, list(data[xtick].values)) plt.legend((p1[0], p2[0]), ('total', 'accepted')) plt.show() def univariate_barplots(data, col1, col2='project_is_approved', top=False): # Count number of zeros in dataframe python: https://stackoverflow.com/a/51540521/4084039 temp = pd.DataFrame(project_data.groupby(col1)[col2].agg(lambda x: x.eq(1).sum())).reset_index() # Pandas dataframe grouby count: https://stackoverflow.com/a/19385591/4084039 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.sort_values(by=['total'],inplace=True, ascending=False) if top: temp = temp[0:top] stack_plot(temp, xtick=col1, col2=col2, col3='total') print(temp.head(5)) print("="*50) print(temp.tail(5)) univariate_barplots(project_data, 'school_state', 'project_is_approved', False)Error:
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**¿Obtiene el mismo error si cambia
temp['total'] = pd.DataFrame(project_data.groupby(col1)[col2].agg({'total':'count'})).reset_index()['total']para
temp['total'] = project_data.groupby(col1)[col2].agg(total=('total','count')).reset_index()['total']cambiar
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']para
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']razón: en la nueva versión de pandas, la agregación denominada es el reemplazo recomendado para el enfoque obsoleto de "dictado de dictados" para nombrar la salida de agregaciones específicas de columna (obsoleto groupby.agg() con un diccionario al cambiar el nombre).
fuente: https://pandas.pydata.org/pandas-docs/stable/whatsnew/v0.25.0.html
Este error también ocurre si una columna especificada en el dictado de la función de agregación no existe en el marco de datos:
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 supportedTengo un problema similar al de @akshay jindal, pero verifico la documentación sugerida por @artikay Khanna, el problema se resolvió, se ajustaron algunas funciones, el antiguo está en desuso. Aquí está la advertencia de código proporcionada por última vez que se ejecutó.
/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.Por lo tanto, sugeriré intentar
grouper.agg(name_1=func_1, name_2=func_2)Espero que esto ayude
Probé todas las soluciones y resultó ser el error con el nombre. Si el nombre de su columna tiene algunas palabras clave incorporadas como "en", "es", etc., está arrojando un error. En mi caso, el nombre de mi columna es "Puntos en polígono" y he resuelto el problema cambiando el nombre de la columna a "Puntos"
La solución de @Rishi funcionó para mí. El nombre original de la columna en mi marco de datos era net_value_budgeted_rate , que era esencialmente el valor en dólares de la venta. Lo cambié a dollars y funcionó.
En lugar de usar .agg({'total':'count'})) , puede pasar el nombre con la función como una lista de tupla como .agg([('total', 'count')]) y usar el mismo para Avg también. Espero que funcione.
No es una solución muy elegante, pero esta funciona. Como cambiar el nombre de la columna está en desuso con la forma en que lo está haciendo. Pero hay trabajo alrededor. Cree una variable temporal ' aprobada ', almacene el col2 en ella. Porque cuando aplica la función agg, los valores de la columna original cambiarán con el nombre de la columna. Puede conservar el nombre de la columna, pero luego los valores en esa columna cambiarán. Entonces, para preservar el marco de datos original y tener dos nuevas columnas con los nombres deseados, puede usar el siguiente código.
approved = temp[col2] temp = pd.DataFrame(project_data.groupby(col1)[col2].agg([('Avg','mean'),('total','count')]).reset_index()) temp[col2] = approvedPD: Parece una tarea de AAIC, estoy trabajando en lo mismo :)
A veces es conveniente mantener un aggdict de cómo se debe transformar cada columna bajo la agregación que funcionará con diferentes conjuntos de columnas y diferentes grupos por columnas. Puede hacer esto con la nueva sintaxis bastante fácilmente descomprimiendo el dict con **. Aquí hay un ejemplo de trabajo mínimo para datos simples.
dfx=pd.DataFrame(columns=["A","B","C"],data=np.random.randint(0,5,size=(10,3))) #dfx # # ABC #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 Tal vez cuando agregas quieres la primera "A" , la última "B" , la media "C" y, a veces, tu tubería tiene una "D" (pero no esta vez) de la que también quieres la media.
aggdict = {"A":lambda x: x.iloc[0], "B": lambda x: x.iloc[-1], "C" : "mean" , "D":lambda x: "mean"} Puede crear un dict simple como en los viejos tiempos y luego desempaquetarlo con ** filtrado en las claves relevantes:
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}) # AB #C #1 4 2 #2 0 0 #3 1 4 #4 2 3Y luego puedes cortar y trocear como quieras con la misma sintaxis:
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]Encontré el camino: En lugar de ir como
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']Haz lo siguiente:
g2 = df.groupby(["Description","CustomerID"],as_index=False).agg({'Quantity':{np.max,np.min,np.mean}}) g2.columns = ["Description","CustomerID","maxQ","minQ",'meanQ']¡Tuve el mismo error y así es como lo resolví!
Info = pd.DataFrame(df.groupby("school_state").agg(Approved=("project_is_approved",lambda x: x.eq(1).sum()),Total=("project_is_approved","count"),Avg=("project_is_approved","mean"))).reset_index().sort_values(by=["Total"],ascending=False).head()Puede dividir esto en comandos individuales para una mejor legibilidad.