conte a frequência em que um valor ocorre em uma coluna de quadro de dados


313

Eu tenho um conjunto de dados

|category|
cat a
cat b
cat a

Gostaria de poder retornar algo como (mostrando valores e frequência únicos)

category | freq |
cat a       2
cat b       1


94
Você está procurando df["category"].value_counts()?
DSM

Ao usar "df [" categoria "]. Value_counts ()", ele diz que é um int? mas retorna o nome da coluna como índice? É um objeto de quadro de dados ou de alguma forma combina uma série (as contagens) e os valores originais da coluna original?
yoshiserry

@yoshiserry É uma série Pandas fazer type(df['category'].value_counts())e ele vai dizer isso
EdChum

Eu fiz, e fiquei surpresa com isso, mas faz sentido quanto mais eu penso sobre isso. Depois de fazer isso, o valor conta em algumas colunas, e há linhas que eu gostaria de excluir. Sei como remover colunas, mas como excluo linhas?
yoshiserry

Respostas:


414

Use groupbye 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 os documentos on-line: http://pandas.pydata.org/pandas-docs/stable/groupby.html

Também value_counts()como o @DSM comentou, muitas maneiras de esfolar um gato aqui

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

Out[38]:

b    3
a    2
s    2
dtype: int64

Se você deseja adicionar a frequência novamente ao quadro de dados original, use transformpara retornar um índice alinhado:

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 Não, o que você vê é que ele cria uma série que se alinha com o quadro de dados original, ao contrário dos outros métodos que exibem os valores exclusivos e sua frequência, se você quiser apenas adicionar a contagem de frequências ao quadro de dados para o qual você pode usar a transformação isto. É apenas outra técnica, você percebe que ele não reduziu o quadro de dados após a atribuição de volta e não há valores ausentes. Também acho que Dataframes sempre tem um índice Eu não acho que você pode se livrar dele, apenas a redefini-la, atribuir um novo ou usar uma coluna como um índice
EdChum

4
No seu primeiro exemplo de código, o df é atribuído conforme o esperado, mas esta linha: df.groupby ('a'). Count () retorna um quadro de dados vazio. É possível que essa resposta esteja desatualizada com os pandas 0.18.1? Além disso, é um pouco confuso que o nome da sua coluna 'a' seja o mesmo que o valor que você está procurando 'a'. Eu mesmo o editaria, mas como o código não funciona para mim, não posso ter certeza das minhas edições.
28416 Alex

1
@Alex você está correto parece que nas versões mais recentes isso não funciona mais, parece ser um bug para mim como eu não vejo por que não
EdChum

1
Por que não usar em df.['a'].value_counts().reset_index()vez de df.groupby('a')['a'].transform('count')?
conjunto

1
@ tandem, eles fazem coisas diferentes, a chamada value_countsgerará uma contagem de frequência, se você quiser adicionar o resultado novamente como uma nova coluna em relação ao seu df original, precisará usar transformconforme detalhado na minha resposta.
EdChum

93

Se você deseja aplicar a todas as colunas, pode usar:

df.apply(pd.value_counts)

Isso aplicará uma função de agregação baseada em coluna (neste caso, value_counts) a cada uma das colunas.


10
Essa é a resposta mais simples. Isso deve estar no topo.
Jeffrey Jose

4
Essa resposta é simples, mas (acredito) a applyoperação não aproveita as vantagens que as matrizes Numpy vetorizadas como as colunas fornecem. Como resultado, o desempenho pode ser um problema em conjuntos de dados maiores.
kuanb

58
df.category.value_counts()

Essa pequena linha de código fornecerá a saída desejada.

Se o nome da sua coluna tiver espaços, você poderá usar

df['category'].value_counts()

2
Ou use [] se o nome da coluna tiver espaço. df['category 1'].value_counts()
Jacob Kalakal Joseph 11/10

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

value_counts - Retorna um objeto contendo contagens de valores únicos

apply - count frequency em todas as colunas. Se você definir axis=1, obterá frequência em todas as linhas

fillna (0) - torna a saída mais sofisticada. NaN alterado para 0


1
Isso é muito poderoso ao contar ocorrências de um valor entre colunas para a mesma linha !!
26617 amc

14

Em 0.18.1, groupbyjuntamente com countnão fornece a frequência 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]

No entanto, os valores únicos e suas frequências são facilmente determinados usando size:

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

Com df.a.value_counts()valores classificados (em ordem decrescente, ou seja, o maior valor primeiro) são retornados por padrão.



5

Se a sua trama de dados tem valores com o mesmo tipo, você também pode definir return_counts=Trueem numpy.unique () .

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

np.bincount () pode ser mais rápido se seus valores forem números inteiros.


4

Sem nenhuma biblioteca, você poderia fazer isso:

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

Exemplo:

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

1

Você também pode fazer isso com os pandas transmitindo suas colunas como categorias primeiro, por dtype="category"exemplo , por exemplo

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

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

e depois chamando describe:

df[cats].describe()

Isso fornecerá uma boa tabela de contagens de valor e um pouco mais :):

    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()

Primeira contagem de valores exclusivos

n_at_most_50k = n_values[0]

Segunda contagem de valores exclusivos

n_greater_50k = n_values[1]

n_values

Resultado:

<=50K    34014
>50K     11208

Name: income, dtype: int64

Resultado:

n_greater_50k,n_at_most_50k:-
(11208, 34014)

0

@metatoaster já apontou isso. Vá em frente Counter. Está super 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

Felicidades!



0
your data:

|category|
cat a
cat b
cat a

solução:

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

0

Eu acredito que isso deve funcionar bem para qualquer lista de colunas do 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"})

A função "column_list" verifica os nomes das colunas e, em seguida, verifica a exclusividade dos valores de cada coluna.


Você pode adicionar uma breve explicação de como seu código funciona para melhorar sua resposta.
DobromirM
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.