Pregunta Quiero crear una columna de value_counts en mi data frame panda


Estoy más familiarizado con R pero quería ver si había una forma de hacerlo en pandas. Quiero crear un recuento de valores únicos a partir de una de mis columnas de marco de datos y luego agregar una nueva columna con esos conteos a mi marco de datos original. He intentado un par de cosas diferentes. Creé una serie de pandas y luego calculé recuentos con el método value_counts. Traté de combinar estos valores con mi marco de datos original, pero las claves con las que me quiero fusionar están en el índice (ix / loc). Cualquier sugerencia o solución sería apreciada

Color Value
Red   100
Red   150
Blue  50

y quería devolver algo así como

Color Value Counts
Red   100   2
Red   150   2 
Blue  50    1

32
2017-07-17 20:08


origen


Respuestas:


df['Counts'] = df.groupby(['Color'])['Value'].transform('count')

Por ejemplo,

In [102]: df = pd.DataFrame({'Color': 'Red Red Blue'.split(), 'Value': [100, 150, 50]})

In [103]: df
Out[103]: 
  Color  Value
0   Red    100
1   Red    150
2  Blue     50

In [104]: df['Counts'] = df.groupby(['Color'])['Value'].transform('count')

In [105]: df
Out[105]: 
  Color  Value  Counts
0   Red    100       2
1   Red    150       2
2  Blue     50       1

Tenga en cuenta que transform('count') ignora NaNs. Si desea contar NaN, use transform(len).


Para el editor anónimo: si obtiene un error mientras usa transform('count') puede deberse a que tu versión de Pandas es demasiado antigua. Lo anterior funciona con pandas versión 0.15 o posterior.


40
2017-07-17 20:20



Mi pensamiento inicial sería utilizar la comprensión de listas como se muestra a continuación, pero, como se señaló en el comentario, esto es más lento que el groupby y transform método. Dejaré esta respuesta para demostrar QUÉ NO HACER:

In [94]: df = pd.DataFrame({'Color': 'Red Red Blue'.split(), 'Value': [100, 150, 50]})
In [95]: df['Counts'] = [sum(df['Color'] == df['Color'][i]) for i in xrange(len(df))]
In [96]: df
Out[100]: 
  Color  Value  Counts
0   Red    100       2
1   Red    150       2
2  Blue     50       1

[3 rows x 3 columns]

El método de @ unutbu se complica para DataFrames con varias columnas que hacen que esto sea más simple de codificar. Si está trabajando con un marco de datos pequeño, esto es más rápido (ver a continuación), pero de lo contrario, debería usar NO utilizar esta.

In [97]: %timeit df = pd.DataFrame({'Color': 'Red Red Blue'.split(), 'Value': [100, 150, 50]}); df['Counts'] = df.groupby(['Color']).transform('count')
100 loops, best of 3: 2.87 ms per loop
In [98]: %timeit df = pd.DataFrame({'Color': 'Red Red Blue'.split(), 'Value': [100, 150, 50]}); df['Counts'] = [sum(df['Color'] == df['Color'][i]) for i in xrange(len(df))]
1000 loops, best of 3: 1.03 ms per loop

2
2018-05-15 02:29



Otra opción:

    z = df['Color'].value_counts 

    z1 = z.to_dict() #converts to dictionary

    df['Count_Column'] = df['Color'].map(z1) 

Esta opción le dará una columna con valores repetidos de los conteos, correspondiente a la frecuencia de cada valor en la columna 'Color'.


1
2017-07-08 19:02



df['Counts'] = df.Color.groupby(df.Color).transform('count')

Puedes hacer esto con cualquier serie: agruparlo solo y llamar transform('count'):

>>> series = pd.Series(['Red', 'Red', 'Blue'])
>>> series.groupby(series).transform('count')
0    2
1    2
2    1
dtype: int64

0
2018-06-30 21:50