Gire un Pandas DataFrame para que tenga el formato correcto: `DataError: No hay tipos numéricos para agregar ‘

Aquí hay un DataFrame de pandas que me gustaría manipular:

import pandas as pd data = {"grouping": ["item1", "item1", "item1", "item2", "item2", "item2", "item2", ...], "labels": ["A", "B", "C", "A", "B", "C", "D", ...], "count": [5, 1, 8, 3, 731, 189, 9, ...]} df = pd.DataFrame(data) print(df) >>> grouping labels count 0 item1 A 5 1 item1 B 1 2 item1 C 8 3 item2 A 3 4 item2 B 731 5 item2 C 189 6 item2 D 9 7 ... ... .... 

Me gustaría “desplegar” este dataframe en el siguiente formato:

 grouping ABCD item1 5 1 8 3 item2 3 731 189 9 .... ........ 

¿Cómo uno haría esto? Pensaría que esto funcionaría:

 pd.pivot_table(df,index=["grouping", "labels"] 

pero me sale el siguiente error:

 DataError: No numeric types to aggregate 

Hay cuatro formas de hacer pandas idiomáticos.

  • No hay duplicados entre las columnas de agrupación. No requiere agregación.
    • pivot
    • set_index
  • Duplicados entre columnas de agrupación. Requiere agregación
    • pivot_table
    • groupby

pivot

 df.pivot('grouping', 'labels', 'count') 

set_index

 df.set_index(['grouping', 'labels'])['count'].unstack() 

pivot_table

 df.pivot_table('count', 'grouping', 'labels') 

groupby

 df.groupby(['grouping', 'labels'])['count'].sum().unstack() 

Todo el rendimiento

 labels ABCD grouping item1 5.0 1.0 8.0 NaN item2 3.0 731.0 189.0 9.0 

sincronización

introduzca la descripción de la imagen aquí

Con el groupby , set_index o pivot_table , puedes completar fácilmente los valores faltantes con fill_value=0

 df.pivot_table('count', 'grouping', 'labels', fill_value=0) df.groupby(['grouping', 'labels'])['count'].sum().unstack(fill_value=0) df.set_index(['grouping', 'labels'])['count'].sum().unstack(fill_value=0) 

Todo el rendimiento

 labels ABCD grouping item1 5 1 8 0 item2 3 731 189 9 

Pensamientos adicionales en groupby

Porque no requerimos ninguna agregación. Si quisiéramos usar groupby , podemos minimizar el impacto de la agregación implícita utilizando un agregador menos impactante.

 df.groupby(['grouping', 'labels'])['count'].max().unstack() 

o

 df.groupby(['grouping', 'labels'])['count'].first().unstack() 

grupo de tiempo groupby

introduzca la descripción de la imagen aquí

Use set_index y unstack :

 df = df.set_index(['grouping','labels']).unstack().rename_axis(None) df.columns = df.columns.droplevel() print(df) 

Salida:

 labels ABCD item1 5 1 8 None item2 3 731 189 9 

Usted pone labels en el índice, pero lo quiere en las columnas:

 >>> df.pivot_table(index='grouping', columns='labels') count labels ABCD grouping item1 5.0 1.0 8.0 NaN item2 3.0 731.0 189.0 9.0 

Tenga en cuenta que esto hace que las columnas sean un MultiIndex. Si no quiere eso, explícitamente pase values : df.pivot_table(index='grouping', columns='labels', values='count') .

Además, tenga en cuenta que el tipo de remodelación que parece estar buscando solo será posible si cada combinación de agrupación y etiqueta tiene exactamente uno o cero valores. Si alguna combinación ocurre más de una vez, debe decidir cómo agregarlos (por ejemplo, sumndo los valores coincidentes).

Tratar:

 In [1]: import pandas as pd ...: ...: data = {"grouping": ["item1", "item1", "item1", "item2", "item2", "item2", "item2"], ...: "labels": ["A", "B", "C", "A", "B", "C", "D"], ...: "count": [5, 1, 8, 3, 731, 189, 9]} ...: In [2]: df = pd.DataFrame(data) In [3]: df.pivot_table(index="grouping",columns="labels") Out[3]: count labels ABCD grouping item1 5 1 8 NaN item2 3 731 189 9