2017-03-25 4 views
1

Ich habe eine Pandas-Spalte, die Strings enthält. Ich möchte eine Wortzählung für alle Wörter in der gesamten Spalte erhalten. Was ist der beste Weg dies zu tun, ohne jeden Wert zu durchlaufen?Pandas Summe aller Wortzahl in Spalte

df = pd.DataFrame({'a': ['some words', 'lots more words', 'hi']}) 

wenn auf df['a'] ausführen, sollten Sie erhalten 6

Antwort

6

Sie könnten die Verwendung vectorized string operations:

In [7]: df["a"].str.split().str.len().sum() 
Out[7]: 6 

, die von

In [8]: df["a"].str.split() 
Out[8]: 
0   [some, words] 
1 [lots, more, words] 
2     [hi] 
Name: a, dtype: object 

In [9]: df["a"].str.split().str.len() 
Out[9]: 
0 2 
1 3 
2 1 
Name: a, dtype: int64 

In [10]: df["a"].str.split().str.len().sum() 
Out[10]: 6 
+0

Auf meinem Weg dahin, v nice – Charlie

3
df.a.str.extractall('(\w+)').count()[0] 

Diese Extrakte kommt alle Wörter (entspricht dem regulären Ausdruck (\w+)) in einer einzelnen Zelle in a und setzt sie in einen neuen Rahmen, der wie etwas aussieht:

   0 
    match  
0 0  some 
    1  words 
1 0  lots 
    1  more 
    2  words 
2 0   hi 

können Sie dann nur ein count auf den Zeilen tun, um die Anzahl der Wörter zu erhalten.

Beachten Sie, dass Sie die Regex immer ändern können, wenn Sie möchten. wenn einige Wörter Satzzeichen könnte zum Beispiel enthalten können Sie ein Wort wie jede Reihe von Nicht-Leerzeichen definieren und so etwas wie:

df.a.str.extractall('(\S+)').count()[0] 

statt

EDIT

Wenn Sie kümmern über die Geschwindigkeit überhaupt, verwenden DSM-Lösung statt:

Grundzeittest %timeit der mit ipython:

%timeit df.a.str.extractall('(\S+)').count()[0] 
1000 loops, best of 3: 1.28 ms per loop 

%timeit df["a"].str.split().str.len().sum() 
1000 loops, best of 3: 447 µs per loop 
+0

Kannst du meine Antwort auch Zeit? Thx – piRSquared

+0

@piRSquared Ich habe ungefähr 100 μs für deine. schnell! – bunji

1

Zahlen von Worten durch str Zählung Blanks + 1, dann Summe()

(df.a.str.count(' ')+1).sum() 
5

Eine weitere Option mit der cat String-Methode erhalten werden können. Wir werden alle Saiten zerschlagen zusammen dann gespalten und

len(df["a"].str.cat(sep=' ').split()) 

aufwendigen Testdaten

li = [ 
    'Lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 
    'adipiscing', 'elit', 'Integer', 'et', 'tincidunt', 'nisl', 
    'Sed', 'pretium', 'arcu', 'nec', 'est', 'hendrerit', 
    'vestibulum', 'Curabitur', 'a', 'nibh', 'justo', 'Praesent', 
    'non', 'pellentesque', 'enim', 'ac', 'nulla', 'ut', 'mi', 
    'diam', 'Aenean', 'placerat', 'ante', 'euismod', 'pulvinar', 
    'augue', 'purus', 'ornare', 'erat', 'pharetra', 'mauris', 
    'sapien', 'vitae', 'In', 'id', 'velit', 'quis', 'mattis', 
    'condimentum', 'Cras', 'congue', 'neque', 'faucibus', 'nisi', 
    'tempor', 'eget', 'Etiam', 'semper', 'Nulla', 'elementum', 
    'magna', 'Donec', 'vel', 'ex', 'dictum', 'Aliquam', 'lobortis', 
    'rutrum', 'ligula', 'Vivamus', 'eu', 'eros', 'Morbi', 'blandit', 
    'rhoncus', 'consequat', 'orci', 'convallis', 'finibus', 'lorem', 
    'urna', 'molestie', 'in', 'sed', 'luctus', 'Ut', 'imperdiet', 
    'felis', 'Mauris', 'nunc', 'malesuada', 'lacinia', 'Vestibulum', 
    'bibendum', 'risus', 'tortor', 'sollicitudin', 'aliquam', 
    'primis', 'ultrices', 'posuere', 'cubilia', 'Curae', 
    'Phasellus', 'turpis', 'auctor', 'venenatis', 'Pellentesque', 
    'fermentum', 'accumsan', 'maximus', 'Fusce', 'ultricies', 
    'tristique', 'sodales', 'suscipit', 'sagittis', 'at', 'cursus', 
    'Nullam', 'dui', 'fringilla', 'mollis', 'Orci', 'varius', 
    'natoque', 'penatibus', 'magnis', 'dis', 'parturient', 'montes', 
    'nascetur', 'ridiculus', 'mus', 'facilisi', 'sem', 'viverra', 
    'feugiat', 'aliquet', 'lectus', 'porta', 'Nunc', 'facilisis', 
    'Duis', 'volutpat', 'scelerisque', 'Maecenas', 'tempus', 
    'massa', 'laoreet', 'gravida', 'odio', 'iaculis', 'libero', 
    'eleifend', 'leo', 'Quisque', 'ullamcorper', 'dignissim', 
    'interdum', 'vulputate', 'lacus', 'vehicula', 'Nam', 'commodo', 
    'dapibus', 'efficitur', 'tellus', 'Suspendisse', 'metus', 
    'Proin', 'quam', 'porttitor', 'egestas' 
] 

df = pd.DataFrame(
    dict(a=[' '.join(
      np.random.choice(li, np.random.randint(5, 10, 1)) 
    ) for _ in range(10000)])) 

naive Test Zählergebnisse

enter image description here

+1

Es ist definitiv der schnellste von allen. Ich werde wahrscheinlich eine ähnliche Variante vorschlagen, die "str.cat" - 'len (" ".join (df ['a'])) geringfügig übertrifft. Split())' –

+0

@NickilMaveli können Sie bitte mein neues Konzept überprüfen. Ich werde es löschen, wenn es falsch ist – piRSquared

+0

Sie müssen nicht. lgtm –