Cómo agregar conteo único con pandas pivot_table

3 minutos de lectura

avatar de usuario de dmi
dmi

Este código:

df2 = (
    pd.DataFrame({
        'X' : ['X1', 'X1', 'X1', 'X1'], 
        'Y' : ['Y2', 'Y1', 'Y1', 'Y1'], 
        'Z' : ['Z3', 'Z1', 'Z1', 'Z2']
    })
)
g = df2.groupby('X')
pd.pivot_table(g, values="X", rows="Y", cols="Z", margins=False, aggfunc="count")

devuelve el siguiente error:

Traceback (most recent call last): ... 
AttributeError: 'Index' object has no attribute 'index'

¿Cómo obtengo una tabla dinámica con recuentos de valores únicos de una columna DataFrame para otras dos columnas?
Esta ahí aggfunc para contar único? ¿Debería estar usando np.bincount()?

NÓTESE BIEN. Estoy consciente de pandas.Series.values_counts() sin embargo, necesito una tabla dinámica.


EDITAR: La salida debe ser:

Z   Z1  Z2  Z3
Y             
Y1   1   1 NaN
Y2 NaN NaN   1

Avatar de usuario de Chang She
chang ella

¿Te refieres a algo como esto?

>>> df2.pivot_table(values="X", index='Y', columns="Z", aggfunc=lambda x: len(x.unique()))

Z   Z1  Z2  Z3
Y             
Y1   1   1 NaN
Y2 NaN NaN   1

Tenga en cuenta que usando len asume que no tienes NAs en su trama de datos. Tu puedes hacer x.value_counts().count() o len(x.dropna().unique()) de lo contrario.

avatar de usuario de julian peng
Julian Peng

Esta es una buena manera de contar las entradas dentro .pivot_table:

>>> df2.pivot_table(values="X", index=['Y','Z'], columns="X", aggfunc="count")

        X1  X2
Y   Z       
Y1  Z1   1   1
    Z2   1  NaN
Y2  Z3   1  NaN

  • Esto hace exactamente lo que se requiere sin una lambda oscura.

    – Alper

    27 de diciembre de 2017 a las 10:45

  • Nota: Pandas ya no acepta filas/columnas como parámetros. pandas.pydata.org/pandas-docs/stable/generated/…

    -Rocky Kev

    31 de diciembre de 2018 a las 5:14

Desde al menos la versión 0.16 de pandas, no toma el parámetro “rows”

A partir de 0.23, la solución sería:

df2.pivot_table(values="X", index='Y', columns="Z", aggfunc=pd.Series.nunique)

que devuelve:

Z    Z1   Z2   Z3
Y                
Y1  1.0  1.0  NaN
Y2  NaN  NaN  1.0

Avatar de usuario de Manavalan Gajapathy
Gajapatía de Manavala

aggfunc=pd.Series.nunique proporciona un recuento distinto. El código completo es el siguiente:

df2.pivot_table(values="X", rows="Y", cols="Z", aggfunc=pd.Series.nunique)

Crédito a @hume por esta solución (ver comentario debajo de la respuesta aceptada). Agregar como respuesta aquí para una mejor visibilidad.

Puede construir una tabla dinámica para cada valor distinto de X. En este caso,

for xval, xgroup in g:
    ptable = pd.pivot_table(xgroup, rows="Y", cols="Z", 
        margins=False, aggfunc=numpy.size)

construirá una tabla dinámica para cada valor de X. Es posible que desee indexar ptable utilizando el xvalue. Con este código, obtengo (por X1)

     X        
Z   Z1  Z2  Z3
Y             
Y1   2   1 NaN
Y2 NaN NaN   1

  • Gracias. Sin embargo, no estoy contando el número de ocurrencias de cada valor distinto de X, estoy contando el número de valores distintos en X para Y y Z.

    – dmi

    12/10/2012 a las 15:45

out = df2.pivot_table(values="X", index='Y', columns="Z", aggfunc=['nunique', 'count', lambda x: len(x.unique()), len])

[out]:
             nunique           count           <lambda>            len          
Z       Z1   Z2   Z3    Z1   Z2   Z3       Z1   Z2   Z3   Z1   Z2   Z3
Y                                                                     
Y1     1.0  1.0  NaN   2.0  1.0  NaN      1.0  1.0  NaN  2.0  1.0  NaN
Y2     NaN  NaN  1.0   NaN  NaN  1.0      NaN  NaN  1.0  NaN  NaN  1.0


out = df2.pivot_table(values="X", index='Y', columns="Z", aggfunc="nunique")

[out]:
Z    Z1   Z2   Z3
Y                
Y1  1.0  1.0  NaN
Y2  NaN  NaN  1.0

out = df2.pivot_table(values="X", index='Y', columns="Z", aggfunc=['nunique'])

[out]:
             nunique          
Z       Z1   Z2   Z3
Y                   
Y1     1.0  1.0  NaN
Y2     NaN  NaN  1.0

  • Gracias. Sin embargo, no estoy contando el número de ocurrencias de cada valor distinto de X, estoy contando el número de valores distintos en X para Y y Z.

    – dmi

    12/10/2012 a las 15:45

Avatar de usuario de Debajyoti Dutta
Debajyoti Dutta

aggfunc=pd.Series.nunique

solo contará valores únicos para una serie; en este caso, contará los valores únicos para una columna. Pero esto no se refleja del todo como una alternativa a aggfunc="count"

Para un conteo simple, es mejor usar aggfunc=pd.Series.count

¿Ha sido útil esta solución?