2013-07-10 16 views
8

Chcę policzyć liczbę wystąpień określonych słów w ramce danych. Wiem, że używanie "str.contains"Liczba wystąpień niektórych słów w ramce danych pandy

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

Obecnie używam powyższego kodu. Czy istnieje metoda dopasowania wyrażenia regularnego i uzyskania liczby wystąpień? W moim przypadku mam dużą ramkę danych i chcę dopasować około 100 ciągów znaków.

Odpowiedz

9

Sposób str.contains akceptuje wyrażenia regularnego:

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. 

na przykład:

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 

policzyć wystąpień można po prostu zsumować tę logiczną Seria:

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

To jest o wiele starsze i prawdopodobnie szybciej, eliminując potrzebę "get". –

+0

@Andy Hayden: Powiedzmy, że chcę 'hello' liczyć i "słowo" liczyć i drukować "" hello "count = 1 ','" słowo "count = 1 '? Czy mogę to zrobić w jednym wierszu kodu? –

+2

A co z 'word_regexs = [r'he ', r'wo']' a następnie utwórz Serię z 'pd.Series ((df.words.str.contains (r) .sum() dla r w word_regexs), word_regexs, name = 'count') '? –

3

Aby policzyć całkowitą liczbę dopasowań, należy użyć s.str.match(...).str.get(0).count().

Jeśli regex zostaną dopasowane kilka unikalnych słów, które mają być rejestrowane oddzielnie, użyj s.str.match(...).str.get(0).groupby(lambda x: x).count()

To działa tak:

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

Sposób match ciąg uchwyty wyrażeń regularnych ...

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

... ale wyniki, jak podano, nie są bardzo wygodne. Metoda ciąg get bierze zapałki jak strun pustych i przekształca wyniki do 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 

... które nie są liczone.

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

: Thanks Allan, pr oblem ze mną nie bierze liczyć, jak o dopasowaniu regex..Andy dostarczyła zgrabną odpowiedź, jak zgodziliście się .. :) –

Powiązane problemy