contare la frequenza con cui si verifica un valore in una colonna del frame di dati


313

Ho un set di dati

|category|
cat a
cat b
cat a

Vorrei poter restituire qualcosa del genere (mostrando valori e frequenza unici)

category | freq |
cat a       2
cat b       1



Quando si utilizza "df [" categoria "]. Value_counts ()" si dice che è un int? ma restituisce il nome della colonna come indice? È un oggetto dataframe o combina in qualche modo una serie (i conteggi) e i valori di colonna univoci originali?
yoshiserry,

@yoshiserry è una serie di Pandas type(df['category'].value_counts())e lo dirà
EdChum

L'ho fatto e ne sono rimasto sorpreso, ma ha senso più ci penso. Dopo aver fatto questo, il valore conta su alcune colonne, ci sono righe che vorrei escludere. So come rimuovere le colonne ma come posso escludere le righe?
yoshiserry,

Risposte:


414

Usa 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]

Consulta i documenti online: http://pandas.pydata.org/pandas-docs/stable/groupby.html

Inoltre, value_counts()come ha commentato @DSM, molti modi per scuoiare un gatto qui

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

Out[38]:

b    3
a    2
s    2
dtype: int64

Se si desidera aggiungere di nuovo la frequenza al frame di dati originale, utilizzare transformper restituire un indice allineato:

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, quello che vedi è che crea una serie che si allinea al frame di dati originale, a differenza degli altri metodi che visualizzano i valori univoci e la loro frequenza, se volessi solo aggiungere il conteggio di frequenza al frame di dati per cui puoi usare la trasformazione per Questo. È solo un'altra tecnica, noterai che non ha compresso il frame di dati dopo averlo assegnato e non ci sono valori mancanti. Inoltre penso che i Dataframe abbiano sempre un indice, non penso che tu possa liberartene, ripristinarlo, assegnarne uno nuovo o usare una colonna come indice
EdChum

4
Nel tuo primo esempio di codice, df viene assegnato come previsto, ma questa riga: df.groupby ('a'). Count () restituisce un frame di dati vuoto. È possibile che questa risposta non sia aggiornata con Panda 0.18.1? Inoltre, è un po 'confuso che il nome della colonna "a" sia uguale al valore che stai cercando "a". Vorrei modificarlo da solo, ma poiché il codice non funziona per me non posso essere sicuro delle mie modifiche.
Alex,

1
@Alex hai ragione sembra che nelle ultime versioni questo non funzioni più, mi sembra un bug perché non vedo perché no
EdChum,

1
Perché non usare df.['a'].value_counts().reset_index()invece di df.groupby('a')['a'].transform('count')?
tandem il

1
@tandem, fanno cose diverse, la chiamata value_countsgenererà un conteggio di frequenza, se si desidera aggiungere nuovamente il risultato come nuova colonna rispetto al proprio df originale, è necessario utilizzare transformcome indicato nella mia risposta.
EdChum,

93

Se si desidera applicare a tutte le colonne è possibile utilizzare:

df.apply(pd.value_counts)

Ciò applicherà una funzione di aggregazione basata su colonna (in questo caso value_counts) a ciascuna delle colonne.


10
Questa è la risposta più semplice. Questo dovrebbe essere al top.
Jeffrey Jose,

4
Questa risposta è semplicemente ma (credo) l' applyoperazione non sfrutta i vantaggi che le vettori di Numpy vettorializzano come forniscono le colonne. Di conseguenza, le prestazioni potrebbero essere un problema per set di dati più grandi.
kuanb,

58
df.category.value_counts()

Questa breve riga di codice ti darà l'output che desideri.

Se il nome della tua colonna ha spazi che puoi usare

df['category'].value_counts()

2
Oppure usa [] se il nome della colonna ha spazio. df['category 1'].value_counts()
Jacob Kalakal Joseph,

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

value_counts - Restituisce un oggetto contenente conteggi di valori univoci

applica - conta la frequenza in ogni colonna. Se si imposta axis=1, si ottiene la frequenza in ogni riga

fillna (0) - rende l'output più elaborato. NaN modificato a 0


1
Questo è molto potente quando si contano le occorrenze di un valore tra le colonne per la stessa riga !!
amc

14

In 0.18.1 groupbyinsieme a countnon viene fornita la frequenza di valori univoci:

>>> 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]

Tuttavia, i valori univoci e le loro frequenze sono facilmente determinabili utilizzando size:

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

Con i df.a.value_counts()valori ordinati (in ordine decrescente, ovvero prima il valore più grande) vengono restituiti per impostazione predefinita.



5

Se il tuo DataFrame ha valori con lo stesso tipo, puoi anche impostare return_counts=Truein numpy.unique () .

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

np.bincount () potrebbe essere più veloce se i tuoi valori sono numeri interi.


4

Senza librerie, puoi invece farlo:

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

Esempio:

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

1

Puoi anche farlo con i panda trasmettendo prima le tue colonne come categorie, ad dtype="category"es

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

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

e poi chiamando describe:

df[cats].describe()

Questo ti darà una bella tabella di conteggi di valore e un po 'di più :):

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

Primo conteggio del valore univoco

n_at_most_50k = n_values[0]

Secondo conteggio del valore univoco

n_greater_50k = n_values[1]

n_values

Produzione:

<=50K    34014
>50K     11208

Name: income, dtype: int64

Produzione:

n_greater_50k,n_at_most_50k:-
(11208, 34014)

0

@metatoaster l'ha già sottolineato. Andare per Counter. È velocissimo.

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"])

Timer

%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

Saluti!



0
your data:

|category|
cat a
cat b
cat a

soluzione:

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

0

Credo che questo dovrebbe funzionare bene per qualsiasi elenco di colonne 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 funzione "column_list" controlla i nomi delle colonne e quindi controlla l'unicità dei valori di ciascuna colonna.


Puoi aggiungere una breve spiegazione di come funziona il tuo codice per migliorare la tua risposta.
DobromirM,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.