2013-07-10 19 views
8

Voglio contare il numero di occorrenze di determinate parole in un frame di dati. So che l'utilizzo di "str.contains"Conteggio occorrenze di determinate parole in dataframe panda

a = df2[df2['col1'].str.contains("sample")].groupby('col2').size() 
n = a.apply(lambda x: 1).sum() 

Attualmente sto usando il codice di cui sopra. Esiste un metodo per abbinare le espressioni regolari e ottenere il conteggio delle occorrenze? Nel mio caso ho un grande dataframe e voglio abbinare circa 100 stringhe.

risposta

9

Il metodo str.contains accetta un'espressione regolare:

Definition: df.words.str.contains(self, pat, case=True, flags=0, na=nan) 
Docstring: 
Check whether given pattern is contained in each string in the array 

Parameters 
---------- 
pat : string 
    Character sequence or regular expression 
case : boolean, default True 
    If True, case sensitive 
flags : int, default 0 (no flags) 
    re module flags, e.g. re.IGNORECASE 
na : default NaN, fill value for missing values. 

Ad esempio:

In [11]: df = pd.DataFrame(['hello', 'world'], columns=['words']) 

In [12]: df 
Out[12]: 
    words 
0 hello 
1 world 

In [13]: df.words.str.contains(r'[hw]') 
Out[13]: 
0 True 
1 True 
Name: words, dtype: bool 

In [14]: df.words.str.contains(r'he|wo') 
Out[14]: 
0 True 
1 True 
Name: words, dtype: bool 

Per contare le occorrenze si può semplicemente riassumere Serie booleana:

In [15]: df.words.str.contains(r'he|wo').sum() 
Out[15]: 2 

In [16]: df.words.str.contains(r'he').sum() 
Out[16]: 1 
+0

Questo è molto più ordinato e probabilmente più veloce, ovviando alla necessità di "get''. –

+0

@Ady Hayden: Diciamo che voglio "ciao" conteggio e "parola" conteggio e stampa "" ciao "conteggio = 1", "" parola "conteggio = 1"? Posso farlo in una riga di codice? –

+2

Che dire di 'word_regexs = [r'he ', r'wo']' e quindi creare una serie con 'pd.Series ((df.words.str.contains (r) .sum() per r in word_regexs), word_regexs, name = 'count') '? –

3

Per contare il numero totale di corrispondenze, utilizzare s.str.match(...).str.get(0).count().

Se il regex sarà la corrispondenza più parole uniche, per essere conteggiati singolarmente, utilizzare s.str.match(...).str.get(0).groupby(lambda x: x).count()

Funziona così:

In [12]: s 
Out[12]: 
0 ax 
1 ay 
2 bx 
3 by 
4 bz 
dtype: object 

Il metodo match stringa gestisce le espressioni regolari ...

In [13]: s.str.match('(b[x-y]+)') 
Out[13]: 
0  [] 
1  [] 
2 (bx,) 
3 (by,) 
4  [] 
dtype: object 

... ma i risultati, come indicato, non sono molto convenienti. Il metodo stringa get prende le partite come stringhe e converte i risultati vuote NaNs ...

In [14]: s.str.match('(b[x-y]+)').str.get(0) 
Out[14]: 
0 NaN 
1 NaN 
2  bx 
3  by 
4 NaN 
dtype: object 

... che non vengono contati.

In [15]: s.str.match('(b[x-y]+)').str.get(0).count() 
Out[15]: 2 
+0

: Grazie Allan, pr oblem con me non sta prendendo il conteggio, che ne dici di abbinamento regex..Andy ha fornito una risposta chiara come hai concordato .. :) –