contar la frecuencia con la que se produce un valor en una columna de marco de datos


313

Tengo un conjunto de datos

|category|
cat a
cat b
cat a

Me gustaría poder devolver algo como (mostrando valores y frecuencia únicos)

category | freq |
cat a       2
cat b       1


94
¿Está buscando df["category"].value_counts()?
DSM

Cuando se usa "df [" category "]. Value_counts ()" dice que es un int? pero devuelve el nombre de la columna como índice? ¿Es un objeto de marco de datos o de alguna manera combina una serie (los recuentos) y los valores de columna únicos originales?
yoshiserry

@yoshiserry es una serie de Pandas type(df['category'].value_counts())y lo dirá
EdChum el

Lo hice, y eso me sorprendió, pero tiene sentido cuanto más lo pienso. Después de hacer esto, el valor cuenta en algunas columnas, hay filas que me gustaría excluir. Sé cómo eliminar columnas, pero ¿cómo excluyo filas?
yoshiserry

Respuestas:


414

Uso groupbyy count:

In [37]:
df = pd.DataFrame({'a':list('abssbab')})
df.groupby('a').count()

Out[37]:

   a
a   
a  2
b  3
s  2

[3 rows x 1 columns]

Consulte los documentos en línea: http://pandas.pydata.org/pandas-docs/stable/groupby.html

También, value_counts()como ha comentado @DSM, muchas formas de desollar un gato aquí

In [38]:
df['a'].value_counts()

Out[38]:

b    3
a    2
s    2
dtype: int64

Si desea volver a agregar la frecuencia al marco de datos original, use transformpara devolver un índice alineado:

In [41]:
df['freq'] = df.groupby('a')['a'].transform('count')
df

Out[41]:

   a freq
0  a    2
1  b    3
2  s    2
3  s    2
4  b    3
5  a    2
6  b    3

[7 rows x 2 columns]

@yoshiserry No, lo que ve es que crea una serie que se alinea con el marco de datos original, a diferencia de los otros métodos que muestran los valores únicos y su frecuencia, si solo desea agregar el recuento de frecuencia al marco de datos, puede usar transform para esta. Es solo otra técnica, observa que no ha colapsado el marco de datos después de asignar de nuevo y no faltan valores. También creo que los Dataframes siempre tienen un índice, no creo que pueda deshacerse de él, solo restablecerlo, asignar uno nuevo o usar una columna como índice
EdChum

44
En su primer ejemplo de código, df se asigna como se esperaba, pero esta línea: df.groupby ('a'). Count () devuelve un marco de datos vacío. ¿Es posible que esta respuesta esté desactualizada con pandas 0.18.1? Además, es un poco confuso que el nombre de su columna 'a' sea el mismo que el valor que está buscando 'a'. Lo editaría yo mismo pero como el código no funciona para mí, no puedo estar seguro de mis ediciones.
Alex

1
@Alex, tienes razón, parece que en las últimas versiones esto ya no funciona, me parece un error ya que no veo por qué no
EdChum

1
¿Por qué no usar en df.['a'].value_counts().reset_index()lugar de df.groupby('a')['a'].transform('count')?
Tándem

1
@tandem, hacen diferentes cosas, las llamadas value_countsgenerarán un recuento de frecuencia, si desea agregar el resultado como una nueva columna contra su df original, entonces tendría que usarlo transformcomo se detalla en mi respuesta.
EdChum

93

Si desea aplicar a todas las columnas, puede usar:

df.apply(pd.value_counts)

Esto aplicará una función de agregación basada en columnas (en este caso value_counts) a cada una de las columnas.


10
Esta es la respuesta más simple. Esto debería estar en la parte superior.
Jeffrey Jose

44
Esta respuesta es simple pero (creo) que la applyoperación no aprovecha las ventajas que las matrices vectorizadas de Numpy proporcionan como columnas. Como resultado, el rendimiento podría ser un problema en conjuntos de datos más grandes.
kuanb

58
df.category.value_counts()

Esta pequeña línea de código le dará el resultado que desea.

Si el nombre de su columna tiene espacios que puede usar

df['category'].value_counts()

2
O use [] si el nombre de la columna tiene espacio. df['category 1'].value_counts()
Jacob Kalakal Joseph

19
df.apply(pd.value_counts).fillna(0)

value_counts : devuelve el objeto que contiene recuentos de valores únicos

aplicar - cuenta la frecuencia en cada columna. Si configura axis=1, obtiene frecuencia en cada fila

fillna (0): hace que la salida sea más elegante. Cambió NaN a 0


1
¡Esto es muy poderoso al contar las ocurrencias de un valor a través de columnas para la misma fila!
amc

14

En 0.18.1 groupbyjunto con countno da la frecuencia de valores únicos:

>>> df
   a
0  a
1  b
2  s
3  s
4  b
5  a
6  b

>>> df.groupby('a').count()
Empty DataFrame
Columns: []
Index: [a, b, s]

Sin embargo, los valores únicos y sus frecuencias se determinan fácilmente usando size:

>>> df.groupby('a').size()
a
a    2
b    3
s    2

Con los df.a.value_counts()valores ordenados (en orden descendente, es decir, el valor más grande primero) se devuelven de forma predeterminada.



5

Si su DataFrame tiene valores con el mismo tipo, también puede establecerlo return_counts=Trueen numpy.unique () .

index, counts = np.unique(df.values,return_counts=True)

np.bincount () podría ser más rápido si sus valores son enteros.


4

Sin ninguna biblioteca, puede hacer esto en su lugar:

def to_frequency_table(data):
    frequencytable = {}
    for key in data:
        if key in frequencytable:
            frequencytable[key] += 1
        else:
            frequencytable[key] = 1
    return frequencytable

Ejemplo:

to_frequency_table([1,1,1,1,2,3,4,4])
>>> {1: 4, 2: 1, 3: 1, 4: 2}

1

También puede hacer esto con pandas transmitiendo primero sus columnas como categorías, por dtype="category"ejemplo , p. Ej.

cats = ['client', 'hotel', 'currency', 'ota', 'user_country']

df[cats] = df[cats].astype('category')

y luego llamando describe:

df[cats].describe()

Esto le dará una buena tabla de recuento de valores y un poco más :):

    client  hotel   currency    ota user_country
count   852845  852845  852845  852845  852845
unique  2554    17477   132 14  219
top 2198    13202   USD Hades   US
freq    102562  8847    516500  242734  340992

0
n_values = data.income.value_counts()

Primer recuento de valor único

n_at_most_50k = n_values[0]

Segundo recuento de valor único

n_greater_50k = n_values[1]

n_values

Salida:

<=50K    34014
>50K     11208

Name: income, dtype: int64

Salida:

n_greater_50k,n_at_most_50k:-
(11208, 34014)

0

@metatoaster ya lo ha señalado. Ir por Counter. Está ardiendo rápido.

import pandas as pd
from collections import Counter
import timeit
import numpy as np

df = pd.DataFrame(np.random.randint(1, 10000, (100, 2)), columns=["NumA", "NumB"])

Temporizadores

%timeit -n 10000 df['NumA'].value_counts()
# 10000 loops, best of 3: 715 µs per loop

%timeit -n 10000 df['NumA'].value_counts().to_dict()
# 10000 loops, best of 3: 796 µs per loop

%timeit -n 10000 Counter(df['NumA'])
# 10000 loops, best of 3: 74 µs per loop

%timeit -n 10000 df.groupby(['NumA']).count()
# 10000 loops, best of 3: 1.29 ms per loop

¡Salud!



0
your data:

|category|
cat a
cat b
cat a

solución:

 df['freq'] = df.groupby('category')['category'].transform('count')
 df =  df.drop_duplicates()

0

Creo que esto debería funcionar bien para cualquier lista de columnas de DataFrame.

def column_list(x):
    column_list_df = []
    for col_name in x.columns:
        y = col_name, len(x[col_name].unique())
        column_list_df.append(y)
return pd.DataFrame(column_list_df)

column_list_df.rename(columns={0: "Feature", 1: "Value_count"})

La función "column_list" verifica los nombres de las columnas y luego verifica la unicidad de los valores de cada columna.


Puede agregar una breve explicación de cómo funciona su código para mejorar su respuesta.
DobromirM
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.