Estoy buscando una manera eficiente de calcular las tablas dinámicas y los conteos de frecuencia, pero mi requisito es que si conozco el dominio de una variable, entonces se deben realizar los conteos para cada valor en el dominio, no solo los valores que se observan en las muestras .

Por ejemplo, con el siguiente código, el método Series.count_values genera:

2    2
1    2

Pero sé que el dominio de mi variable es [0,1,2], así que realmente quiero:

0    0
1    2
2    2

Aquí hay una muestra de código para reproducir el ejemplo.

import pandas as pd
import numpy as np

s=pd.Series([1,2,2,1])

def my_value_counts(s,levels):
#levels is a numpy array
    c=s.value_counts()
    foundl=sorted(c.index)
    counts=np.zeros_like(levels)
    for i,l in enumerate(levels):
        if l in foundl:
            counts[i]=c.loc[l]
    return counts

print "Original method"
print s.value_counts()
print "with all levels"
print my_value_counts(s,np.arange(3))

Mi pregunta es: ¿mi código es ineficiente? Parece que un poco de clasificación podría ayudar. Y si es así, ¿hay alguna manera de hacer esto sin tener que volver a crear una tabla de frecuencias y hacer coincidir sus valores con la salida de values_count como hice en el código?

Gracias AL

1
titus 13 may. 2016 a las 20:19

3 respuestas

La mejor respuesta
In [80]: pd.Series([1,2,2,1]).value_counts().reindex(np.arange(3))
Out[80]: 
0   NaN
1     2
2     2
dtype: float64

In [81]: pd.Series([1,2,2,1]).value_counts().reindex(np.arange(3)).fillna(0)
Out[81]: 
0    0
1    2
2    2
dtype: float64
1
Mike Graham 13 may. 2016 a las 17:45

¿Eficiente? Probablemente. ¿Elegante? Menos.

s.value_counts().combine_first(pd.Series(np.zeros(3)))
0
CubeJockey 13 may. 2016 a las 18:32

Un método sería reindex el value_counts con un nuevo índice que comience desde 0 hasta el valor máximo + 1:

In [12]:
s=pd.Series([1,2,2,1])
val = s.value_counts()
val.reindex(np.arange(0, s.max()+1)).fillna(0)

Out[12]:
0    0
1    2
2    2
dtype: float64
3
EdChum - Reinstate Monica 13 may. 2016 a las 17:39